I am trying to read values from excel sheet cells, where I find values like 123,10000. So there are always 5 decimal places. Now, I read in this value from a cell like this:
reportedAmount = _converter.ToDecimalOrZero(row[25].ToString());
The ToDecimalOrZero method looks like this:
internal decimal ToDecimalOrZero(string v)
{
String formattedDecimalInput = String.Format("{0:0.00000}", v);
try
{
return Convert.ToDecimal(formattedDecimalInput);
}
catch
{
return Convert.ToDecimal(String.Format("{0:0.00000}", 0));
}
}
Now, the issue is that the returned values will always have no trailing zeroes, regardless of how the input is. What I notice when doing some simple debugging is that the method that reads out the value from a cell is the one that removes the zeroes. However, what is confusing to me is that String.Format("{0:0.00000}", v) does not return the value with 5 decimal places, but returns the same format that the value we gave to it had (the one without trailing zeroes). Any ideas? Thank you.
Related
The headline doesn't really fit but I'm not good at explaining in just one headline. Here goes: I want to put a double variable that changes depending on userinput into a Sortedlist and then loop through it so that it the output would be something like this:
Distance: 1
Distance : 2
Distance : 3
I can't use an arraylist because I don't know how many double values I will get.
I'm not really sure what you are asking for, so a wrote a code that will be "useful" for two scenarios: First, you want to access the last value that the user wrote. Second, you want to access all values on the list. And third, you want all of that on a single variable.
public class DistanceList : List<double>
{
public override string ToString()
{
int count = 1;
string resultString = String.Empty;
foreach (var item in this)
{
resultString = String.Concat(resultString, "Distance ", count.ToString(), ": ", item.ToString(), ";");
count = +1;
}
return resultString;
}
public static implicit operator double(DistanceList list)
{
return list.Single();
}
}
This class overrides the ToString method, and loops through all the values and add them on a string, giving the output you stated on your question "the output would be something like this: Distance: 1 Distance : 2 Distance : 3".
If you want the last value there is a implicit conversion for double which return the only value for the list, for one value will work just like a regular variable, for more than one value if you try to use as a double it will just trow an exception.
Just be aware that you will not be able to write directly to this variable and expect to add the item on the list, you will still need to use the List<T>().Add method.
But I really hope that it is not what you are asking for, because this kind of design will cause you a lot of trouble down the road.
Will you always be checking whether there is just one item so you can treat it as a double, or need to deal with many values? You will probably forget doing so somewhere...
This class only transforms them on a string, what if you need them as doubles to sum them up or something? You might end up parsing that string back into a List<double>...
I am new to c# programming and I recently bumped into one problem which looks pretty basic.I store the string value like SV_1 in the variable lastServiceNo and split it using Split function and the result is stored in string array called index.Basically index[1] has some numeric value bt as string. now I want to convert string into int. In the following code , it behaves as expected until parse function is encountered.I could not understand why does this parse function returning 0 as index[1] has some numeric value in it. Can somebody point the problem please??
public string GenerateServiceNo() {
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return "SV_"+(lastIndex++).ToString();
}
int.Parse(string s) throws an exception if the number is too bug in terms of data size or the string "s" is not in the correct numerical format.
The format that this method accepts is "[ws][sign]number[ws]" where:
[ws] is optional for one or more whitespace(" ")
[sign] is optional for "+" or "-"
Check here for the full reference.
Thus said, I can assure you that if int.Parse(index[1]) returns 0 then that means index[1] equals "[ws][sign]0[ws]" using the transcript above.
However, looking at your code, I can conclude that you're incrementing a local variable after assignment without using its incremented value afterwards. Perhaps you meant that this operation shouldn't be 0?
If that's the case then I believe this is what you're trying to achieve:
public string GenerateServiceNo()
{
DataAccessLayer.DataAccessLayer dlObj= new DataAccessLayer.DataAccessLayer();
string lastServiceNo = dlObj.GetLastServiceNo();
string[] index = lastServiceNo.Split('_');
int lastIndex = int.Parse(index[1]);
return string.Format("SV_{0}", ++lastIndex);
}
Assuming index[1] == "0", this method will now return "SV_1".
I have an IF statement as follows:
if (snumber == "9999-999-9999" && cnumber == "999")
{
// 30 Day Trial Demo Key
return "Good";
}
There's a serial number linked to one or multiple cnumbers. In some cases I have a list of 5-20 cnumbers seperated by commas, but that method will not work for what I'm doing. I believe I need to use the Contains method to let the program know any one of those values will work for that serial number. Any insight or work around?
Thanks
C#
You could split your list of cnumbers by comma and iterate the array checking each cnumber against your value.
if(snumber == "9999-999-9999")
{
var cnumbers = listOfCnumbers.Split(',');
foreach(var cnumber in cnumbers)
{
if(cnumber == "999")
{
return "Good";
}
}
}
Might want to replace the hardcoded strings with variables though
I want to convert a string which contains 5 zeros ("00000") into a Int so it can be incremented.
Whenever I convert the string to an integer using Convert.ToInt32(), the value becomes 0.
How can I ensure that the integer stays at a fixed length once converted?
I want to be able to increment the value from "00000" to "00001" and so on so that the value appears with that many digits in a database instead of 0 or 1.
If you are going to down vote question, the least you could do is leave feedback on why you did it...
An integer is an integer. Nothing more.
So the int you have has value zero, there is no way to add any "length" metadata or similar.
I guess what you actually want is, that - at some point - there will be a string again. You want that string to represent your number, but with 5 characters and leading zeroes.
You can achieve that using:
string s = i.ToString("00000")
EDIT
You say you want the numbers to appear like that in your DB.
Ask yourself:
Does it really need to be like that in the DB or is it sufficient to format the numbers as soon as you read them from the database?
Depending on that, format them (as shown above), either when writing to or reading from the DB. Of course, the former case will require more storage space and you cannot really use SQL or similar to perform arithmetic operations!
An integer doesn't have a length, it's purely a numerical value. If you want to keep the length, you have to store the information about the length somewhere else.
You can wrap the value in an object that keeps the length in a property. Example:
public class FormattedInt {
private int _value, _length;
public FormattedInt(string source) {
_length = source.Length;
_value = Int32.Parse(source);
}
public void Increase() {
_value++;
}
public override string ToString() {
return _value.ToString(new String('0', _length));
}
}
Usage:
FormattedInt i = new FormattedInt("0004");
i.Increase();
string s = i.ToString(); // 0005
As olydis says above, an int is just a number. It doesn't specify the display format. I don't recommend storing it padded out with zeroes in a database either. It's an int, store it as an int.
For display purposes, in the app, a report, whatever, then pad out the zeroes.
string s = i.ToString("00000");
What is the best way to take a string which can be empty or contain "1.2" for example, and convert it to an integer? int.TryParse fails, of course, and I don't want to use float.TryParse and then convert to int.
Solution 1: Convert.ToDouble (culture-dependent)
You may using Convert.ToDouble. But, beware! The below solution will work only when the number separator in the current culture's setting is a period character.
var a = (int)Convert.ToDouble("1.2");
Solution 2: Convert.ToDouble (culture-independent)
It's preferable to use IFormatProvider and convert the number in an independent way from the current culture settings:
var a = (int)Convert.ToDouble("1.2", CultureInfo.InvariantCulture.NumberFormat);
Solution 3: Parse & Split
Another way to accomplish this task is to use Split on parsed string:
var a = int.Parse("1.2".Split('.')[0]);
Or:
var a = int.Parse("1.2".Split('.').First());
Notes
If you want to handle empty and null strings, write a method and add string.IsNullOrEmpty condition.
To get decimal separator for the current culture setting, you can use NumberFormatInfo.NumberDecimalSeparator property.
You should also keep eye on rounding to avoid traps.
Select casting, Parse, TryParse or Convert class wisely. Read more at:
How to: Convert a string to an int (C# Programming Guide)
How to: Determine Whether a String Represents a Numeric Value (C# Programming Guide)
I don't know what's wrong with parsing to a float and converting to an int. I doubt that any other way would be more efficient but here's an attempt:
//allows empty strings and floating point values
int ParseInt(string s, bool alwaysRoundDown = false)
{
//converts null/empty strings to zero
if (string.IsNullOrEmpty(s)) return 0;
if (!s.Contains(".")) return int.Parse(s);
string parts = s.Split(".");
int i = int.Parse(parts[0]);
if (alwaysRoundDown || parts.Length==1) return i;
int digitAfterPoint = int.Parse(parts[1][0]);
return (digitAfterPoint < 5) ? i : i+1;
}
In order to globalize the code you would need to replace "." with System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.
int a = (int)Math.Round(float.Parse("0.9"));
You need to round it first unless you want 0.9f being converted to 0 instead of 1.
Maybe you can try to delete everything after floating point using string functions and then convert to int. But seriously I don't think it's better than converting to float and then to int.
I think another way of doing it would be splitting the string into pieces taking the decimal (.) as the delimiter and then parsing for the integer. Of course, I am yet to ask you if the string might contain values like "37.56 miles in 32.65 seconds" type values.
Considering there will be only one value (string or number) in the string, I can think of something in the following line:
public int64 GetInt64(string input)
{
if (string.IsNullOrEmpty(input)) return 0;
// Split string on decimal (.)
// ... This will separate all the digits.
//
string[] words = input.Split('.');
return int.Parse(words[0]);
}
You can use the Visual Basic runtime Library to accomplish this from c#.
You need to add a reference to the assembly Microsoft.VisualBasic.dll to your solution.
Then the following code will do your conversion:
using VB = Microsoft.VisualBasic.CompilerServices;
class Program
{
static void Main(string[] args)
{
int i = VB.Conversions.ToInteger("1.2");
}
}
I had this same problem and ended up using a hybrid of Mark's and Dariusz':
if (num == "")
{
num = "0.00";
}
var num1 = (float)Convert.ToDouble(num);