Question

I'm trying to convert and exponential number 1.11111117E+9 which is actually a 10 digit number '1111111111'. When I'm trying to convert this exponential number using decimal.TryParse method it is making last 3 digits as zero and giving the number as '111111000'. This is happening with any 10 digit number.

   decimal amount;
   decimal.TryParse("1.11111117E+9", NumberStyles.Any, null, out amount);

This is weird but I'm not able to figure out what's the issue here, can anybody tell me what's wrong in this?

Edit: Sorry for the misleading question. As Henrik mentioned in his answer is exactly what I'm facing.

float f = 1111111111;
string s = f.ToString();
decimal amount;
decimal.TryParse(s, NumberStyles.Any, null, out amount);

This will always return 1111111000? How do I address this issue to get the correct value? Change it to Double or Decimal from float datatype is the solution or anything else?

Was it helpful?

Solution

It's easy to round-trip a float value...

float f = 1111111111;
string s = f.ToString("r"); // r = roundtrip
float g = float.Parse(s);

Now f and g will be the same... but that doesn't mean that either value is exactly 1111111111... because that value can't be represented as a float. The nearest value exactly representable as a float is 1111111168... which is why you're getting the 7 at the end of the scientific representation.

Basically, you shouldn't be using float for this in the first place. From the docs for System.Single:

By default, a Single value contains only 7 decimal digits of precision, although a maximum of 9 digits is maintained internally.

So trying to store a 10 digit number and expecting it to be stored exactly is a fool's errand.

It's hard to say whether you should be using double or decimal - it depends on what value you're really trying to store. If it's a "natural" value like weight or height, I'd go for double. If it's a "human" value like a price, I'd use decimal.

OTHER TIPS

This

decimal amount;
decimal.TryParse("1.11111117E+9", NumberStyles.Any, 
    CultureInfo.InvariantCulture, out amount);

sets amount to 1111111170M, as expected.

Note the CultureInfo.InvariantCulture, so it does not depend on your local settings.

Update: I suspect your real code looks something like this:

float f = 1111111111;
string s = f.ToString();
decimal amount;
decimal.TryParse(s, NumberStyles.Any, null, out amount);

f is displayed in the debuger as 1.11111117e+9, s is 1.111111e+9 and amount 1111111000M. The reason for all this is the limited precision of float.

Try this, It works better for me

 decimal dec = Decimal.Parse("1.11111117E+9", System.Globalization.NumberStyles.Any);

You should parse double, not decimal. Scientific notation has no place with decimal.

Update: The exact integer value is 1111111170. Not 111111111 which is about 10 times less than what it should be.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top