I am reading Data from an internal Database.
The code assigns value read from the database to double.
if (Convert.ToDouble(PricefromString) == Price && PriceFound == false)
PricefromString has been read from the database.
Most of the time the code works fine, but i get a FormatException, when the string value is an integer value.
In this particular case, when PricefromString = 77, i get the format exception.
I tried debugging and checked the input string to ToDouble() which is throwing the exception.
Edit: PricefromString has a whitespace tab character at the end attached.
It works perfectly fine when the string is a double value eg. 76.99, 77.01, but i get an FormatException error when price reaches an integer value.
Any leads ?
but i get a FormatException, when the string value is an integer value. In this particular case, when PricefromString = 77, i get the format exception.
No, you don't. Convert.ToDouble will work just fine with a string representing an integer, as you can see for yourself by running this code:
Console.WriteLine(Convert.ToDouble("77"));
It does in fact print out 77.
I would urge you to take a long, hard look at what precisely your input string is.
There might be something else, because if 77 is of String data type then definitely it will work.
Check to see if it does not contain any other characters like currency symbols.
Double.Parse or Convert.ToDouble will throw an exception if it cannot parse the given value.
Whereas Double.TryParse returns a bool indicating whether it succeeded.
Try this:
double value;
Double.TryParse(PricefromString, out value);
By this, you can check if it'll work or not and then do the real conversion once value is boolean true.
For more on this, please refer this answer: Parse v. TryParse
Related
Convert.ToInt32 behaves different when passed string vs float/double literal
var result = Convert.ToInt32(12.4);//returns 12
result = Convert.ToInt32(12.44);//returns 12
result = Convert.ToInt32(12.4444444);//returns 12
result = Convert.ToInt32("12.4"); // Input string was not in a correct format.
I understand different overloads of Convert.ToInt32 are being called for string and float/double
The question is why this inconsistent behavior shouldn't single overload for Convert.ToInt32 throw an exception for loss of precision ?
The question is why this inconsistent behavior shouldn't single
overload for Convert.ToInt32 throw an exception for loss of precision
?
You can think of the utility methods you're currently using to convert from double to int as "casting" i.e (int)12.4, (int)12.44 etc. which in essence means you for sure know that there is high chance that you'll lose data precision, thus in short is like telling the compiler "go ahead and convert it as I don't mind data loss", so, no exception will be thrown whereas the last example that converts from string to int should throw an exception because according to MSDN:
ToInt32(String) method is equivalent to passing value to the
Int32.Parse(String).
and as we all know Int32.Parse(String) throws an exception if the specified string is not in the correct format.
The way I see it, when you start with an float/double and you convert to int you expect a loss of precision. When you have a string that you convert to int you don't expect the parsing to do any losing of data, you just want it to parse and fail if the string is not valid.
You first have to convert your string into double, then cast it to int. or do another convert to int.
result = Convert.ToInt32(Convert.ToDouble("12.4"));
From msdn Convert.ToInt32(string)
Converts the specified string representation of a number to an equivalent 32-bit signed integer.
https://msdn.microsoft.com/en-us/library/sf1aw27b(v=vs.110).aspx
In given examples you can see that converting from double representation to int gives format exception.
so this is clearly by design. you should do it right.
I met an issue about formatting decimal using CultureInfo in C# today.
I have a decimal fValue has a value of 999, when it runs fValue.ToString(CurrentCulture.NumberFormat) 999.0000 is returned.
While debugging in VS I can get the following values in the Watch window:
fValue //returns 999
fValue.ToString(CurrentCulture.NumberFormat) //the issue returns 999.0000
(999M).ToString(CurrentCulture.NumberFormat) //returns 999
CurrentCulture.NumberFormat.NumberDecimalDigits //returns 2
Why the second value returns 999.0000 rather than 999 or 999.00? Sorry for my crap English someone please help.
Using CurrentCulture.NumberFormat.CurrencyDecimalDigits property you will get the number of decimal digits for Decimal type. 999M type is typeof(Decimal), and it is considered as Currency.
The Decimal struct preserves the precision of the values after parsing from a string, and also as computations are performed. The ToString() method correctly indicates the actual internal precision of the value, regardless of which culture is being used.
However, the debugger appears to display the value in its simplest form instead of showing what ToString() would return, which makes things confusing to say the least.
I found one very interesting thing about parsing a string into a float value. The case is that the string value is obtained from a database by using IDbReader Here is an example:
IDbReader myReader;
...
string sValue = myReader.GetValue(0).ToString(); // 12.339123 for example in VS debug and watch
// the content of sValue is what I want to be at this point, but...
Single fValue = Single.Parse(sValue);
// Now the fValue is 12.34!
If I test just Parse for a constant string, the Parse method works fine:
string sValue = "12.339123";
Single fValue = Single.Parse(sValue);
// Now the fValue is 12.339123!
I am not sure why the content of sValue from IDbReader cannot be parsed as original value (as I can see from VS debug). It rounds the float value to a float value with 2 digits after decimal point. How can I get the original value?
How I can get the exactly same value back?
I am using .Net 2.0
Update: I tried to use GetXXX such as GetFloat or GetDecimal methods to get values directly to a float/decimal value. Unfortunately, all those methods seem having similar rounding issue. Only GetValue() and forcing to string will get the exactly same string value as it is in the database. I thought I could do the conversion to a float or decimal value on .Net side, but the Parse() fails in my case. I am not sure why the rounding happen in Parse(). As some suggested the value are there, and it may be VS debug, watch or log caused rounding. However, when I tried to put the float value to a text box, it is rounded to 2 digits after decimal point. It is really a frustrating issue.
I'm not sure how you're looking at that variable and seeing 12.34. If I do the following in LINQPad:
Single.Parse("12.339123")
I get 12.33912. And if I ask it to give me a string with the full round-trip precision:
Single.Parse("12.339123").ToString("r")
I get 12.3391228, which is as close to exactly 12.339123 as you're going to get with a mere single-precision floating-point value.
Conclusion: you're using an imprecise means to inspect the variable's value. The variable itself is almost certainly fine, and holds just as precise a value as floating-point will allow; it's just that the debugger tooltip, or watch window, or logging library, or whatever it is you're using to look at that value, is only showing you a handful of digits.
try this way:
string sValue = myReader.GetValue(0).ToString("F6");
While i am trying to convert a value to Int32, I get an error format exception, meaning the value is not in the proper format. I think I am converting a value in right format though.
Try using Int32.TryParse() you can find documentation on MSDN
You will get FormatException in cases such next:
Convert.ToInt32("foo");
Convert.ToInt32(5.5);
because
FormatException
value does not consist of an optional sign followed by a sequence of digits (0 through 9).
MSDN
string str = "123";
int i = 0;
if (int.TryParse(str, out i))
{
//do your logic here
}
Share your code here, you might missed something
Perhaps the hint is in "I think I am converting a value in right format though"
Are you sure your number is formatted according to your current culture?
If not, it's Int32.TryParse(String, NumberStyles, IFormatProvider, Int32%)
[details here][1] that you should be using
[1]: http://Int32.TryParse Method (String, NumberStyles, IFormatProvider, Int32%)
You can always check the type of the value you are passing in to such functions by using the GetType().
The condition where I was stuck in this issue was conversion of a dynamically generated stringyfied decimal value to int. Figured out the type of the value using the GetType() and first converting it into double then int solved the problem.
What is the difference in C# between Convert.ToDecimal(string) and Decimal.Parse(string)?
In what scenarios would you use one over the other?
What impact does it have on performance?
What other factors should I be taking into consideration when choosing between the two?
There is one important difference to keep in mind:
Convert.ToDecimal will return 0 if it is given a null string.
decimal.Parse will throw an ArgumentNullException if the string you want to parse is null.
From bytes.com:
The Convert class is designed to
convert a wide range of Types, so you
can convert more types to Decimal than
you can with Decimal.Parse, which can
only deal with String. On the other
hand Decimal.Parse allows you to
specify a NumberStyle.
Decimal and decimal are aliases and
are equal.
For Convert.ToDecimal(string),
Decimal.Parse is called internally.
Morten Wennevik [C# MVP]
Since Decimal.Parse is called internally by Convert.ToDecimal, if you have extreme performance requirements you might want to stick to Decimal.Parse, it will save a stack frame.
One factor that you might not have thought of is the Decimal.TryParse method. Both Convert.ToDecimal and Parse throw exceptions if they cannot convert the string to the proper decimal format. The TryParse method gives you a nice pattern for input validation.
decimal result;
if (decimal.TryParse("5.0", out result))
; // you have a valid decimal to do as you please, no exception.
else
; // uh-oh. error message time!
This pattern is very incredibly awesome for error-checking user input.
One common suggestion related to original topic - please use TryParse() as soon as you not really sure that input string parameter WILL be correct number format representation.
Major Difference between Convert.ToDecimal(string) and Decimal.Parse(string)
is that Convert handles Null whereas the other throws an exception
Note: It won't handle empty string.
Convert.ToDecimal apparently does not always return 0. In my linq statement
var query = from c in dc.DataContext.vw_WebOrders
select new CisStoreData()
{
Discount = Convert.ToDecimal(c.Discount)
};
Discount is still null after converting from a Decimal? that is null. However, outside a Linq statement, I do get a 0 for the same conversion. Frustrating and annoying.
Knowing that Convert.ToDecimal is the way to go in most cases because it handles NULL, it, however, does not handle empty string very well. So, the following function might help:
'object should be a string or a number
Function ConvertStringToDecimal(ByVal ValueToConvertToDecimal As Object) As Decimal
If String.IsNullOrEmpty(ValueToConvertToDecimal.ToString) = False Then
Return Convert.ToDecimal(ValueToConvertToDecimal)
Else
Return Convert.ToDecimal(0)
End If
End Function