Share via


Why are floating point values not printed with full precision?

Question

Wednesday, March 8, 2017 8:23 AM

If I have a floating point variable with the value 3.1415927 (binary representation 0b01000000010010010000111111011011) and print it I get 3.141593

And if I convert 3.141593 to binary representation again I get 0b01000000010010010000111111011100

You see the difference:

0b01000000010010010000111111011**011 = **3.1415927

0b01000000010010010000111111011**100 = **3.141593

So I actually lost a little bit of precision.

How can I force C# Console.WriteLine() to output the floating point value with no lost precision?

I used the web page https://www.h-schmidt.net/FloatConverter/IEEE754.html to check this.

All replies (8)

Wednesday, March 8, 2017 4:35 PM | 1 vote

You will keep your precision if you use either decimal or double. Personally, I prefer decimal ... please read my blog post about problems you might encounter doing math on double variables (which is why I prefer decimal): http://geek-goddess-bonnie.blogspot.com/2013/09/double-vs-decimal.html

~~Bonnie DeWitt [C# MVP]

http://geek-goddess-bonnie.blogspot.com


Wednesday, March 8, 2017 10:07 PM | 1 vote

He *said* he was using floating point, and indeed, if you set a float variable to the number he specified, it *does* get rounded, whereas a double doesn't.

float  flt = 3.1415927F;
double dbl = 3.1415927;
Console.WriteLine(flt); //  3.141593
Console.WriteLine(dbl); //  3.1415927 

I guess you didn't try it.  ;0)

~~Bonnie DeWitt [C# MVP]

http://geek-goddess-bonnie.blogspot.com


Wednesday, March 8, 2017 10:20 PM

In fact YOU ARE RIGHT!

You sound surprised!!  ;0)   ;0)

~~Bonnie DeWitt [C# MVP]

http://geek-goddess-bonnie.blogspot.com


Wednesday, March 8, 2017 11:17 PM

So, let me surprise you even more:

float n=3.1415927f;

**Console.WriteLine( Math.Round(n,7) );  // =>  3.1415927 **

As I said in my previous post, it just the rounding operation in action.  :)

In my (very smart) code above, I suppressed rounding, making it happen beyond significant digits...

Unless you happen to round it by more than 7, like maybe 9 instead:

float  flt = 3.1415927F;
Console.WriteLine(Math.Round(flt, 7);  // 3.1415927 
Console.WriteLine(Math.Round(flt, 9)); // 3.141592741  oops!

I still think that one should use decimal. It's not affected by that little issue when rounding to 9 decimal places, like float is (and neither is double, but I still prefer decimals, as noted in my blog post). Both decimal and double, when applying the Math.Round(x, 9) will still be 3.1415927.

~~Bonnie DeWitt [C# MVP]

http://geek-goddess-bonnie.blogspot.com


Thursday, March 9, 2017 6:01 AM

Considering you dont understand floating point numbers, I will skip your articles, and keep reading only articles from experts. :-)

Fine, no problem ... it's your loss!  ;0)

~~Bonnie DeWitt [C# MVP]

http://geek-goddess-bonnie.blogspot.com


Thursday, March 9, 2017 7:28 AM

// 3.1415927 = 0x40490fdb in Hexadecimal Representation
byte[] b = new byte[4] { 0xdb, 0x0f, 0x49, 0x40 };
float x = BitConverter.ToSingle(b, 0);
double xx = x;
Console.WriteLine(x); // Prints 3.141593
Console.WriteLine(xx); // Prints 3.14159274101257

Thursday, March 9, 2017 9:01 AM | 1 vote

// 3.1415927 = 0x40490fdb in Hexadecimal Representation
byte[] b = new byte[4] { 0xdb, 0x0f, 0x49, 0x40 };
float x = BitConverter.ToSingle(b, 0);

Console.WriteLine(x); // Prints 3.141593
byte[] b = new byte[4] { 0xdb, 0x0f, 0x49, 0x40 };
float x = BitConverter.ToSingle(b, 0);

Console.WriteLine(x); // Prints 3.141593
Console.WriteLine(x.ToString("R")); // Prints 3.14159274

You lose a little, you gain a little. Just like life. 

See:

The Round-trip ("R") Format Specifier
https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx#RFormatString

"The round-trip ("R") format specifier is used to ensure that a numeric
value that is converted to a string will be parsed back into the same
numeric value."

For a quick read while you're waiting for the grass to grow:

What Every Computer Scientist Should Know About Floating-Point Arithmetic
http://docs.sun.com/source/806-3568/ncg_goldberg.html

  • Wayne

Thursday, March 9, 2017 4:16 PM

@Erik, I guess what would help is for us to know what you're doing with these numbers and what kind of accuracy/precision do you need in your application? Or are you just experimenting with the different types?  In any case, the Round-trip Format specifier that @Wayne posted a link to seems to be what you need to use.

~~Bonnie DeWitt [C# MVP]

http://geek-goddess-bonnie.blogspot.com