Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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]