Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# float.ToString Rounding Values

Maybe I am missing something but the float.ToString() method rounds numbers, which causes me a lot of headache.

Take a look at the following small code: When entering 12345678 as input, the float number in the debugger is correct but the output of the ToString methods is 12345680 (in any format I've tried...)

Console.WriteLine("Please enter a float number");
float theFloat = float.Parse(Console.ReadLine());
Console.WriteLine(string.Format("You have entered {0}", theFloat.ToString("F")));

And the output:

Please enter a float number
12345678
You have entered 12345680.00

Help will be much appreciated!

like image 610
Nimrod Avatar asked Oct 23 '25 16:10

Nimrod


1 Answers

From the documentation for float:

  • The range of a float is -3.4 × 10^38 to +3.4 × 10^38
  • The precision of a float is 7 digits.

Your number, 12345678, at 8 digits long exceeds the precision, so it is by default being rounded to 7 significant digits, which yields 12345680. (Note the by default.)

However, despite what that Microsoft article says about the precision of a float, in reality it holds up to 9 digits of precision.

The Microsoft documentation for Single.ToString() states:

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

It then goes on to say:

If you require more precision, specify format with the "G9" format specification, which always returns 9 digits of precision, or "R", which returns 7 digits if the number can be represented with that precision or 9 digits if the number can only be represented with maximum precision.

Armed with this information, we can write this code:

Console.WriteLine(12345678f.ToString("G9"));

Which does indeed print 12345678.

What I can't explain is why Microsoft state that a float has 7 digits of precision, and then goes on to let us use 9 digits...

However, note that not all 8 (or 9) decimal digit integers will have an exact representation in a float, as the following code demonstrates (the last digit differs):

Console.WriteLine(16777217f.ToString("R")); // Prints 16777216
like image 118
Matthew Watson Avatar answered Oct 25 '25 05:10

Matthew Watson