1

I am currently learning C# using various resources and one of them is the book titled "C# in a Nutshell".

From Page 37 of the book:

Real Number Rounding Errors

float and double internally represent numbers in base 2. For this reason, only numbers expressible in base 2 are represented precisely. Practically, this means most literals with a fractional component (which are in base 10) will not be represented precisely. For example:

float tenth = 0.1f; // Not quite 0.1
float one = 1f;
Console.WriteLine (one - tenth * 10f); // -1.490116E-08

However, I cannot replicate this. In my case output of Console.WriteLine is exactly 0. I am kind of confused..is it that the example given in the book is not meant to be replicated and given just for some explanation? or it is something else?

I use Visual Studio 2017 with Microsoft .NET framework 4.7.

Update: Screenshot

I tried in Console application as well as in C# Interactive Window. In both the cases the answer is 0.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
D Navi
  • 11
  • 3
  • Works for me, https://dotnetfiddle.net/Widget/8sAnff , however this could be a bitness thing, ie are you in 64bit or 32bit – TheGeneral Jun 10 '19 at 05:33
  • @TheGeneral I am on Windows 10 64-bit – D Navi Jun 10 '19 at 05:45
  • Jon Skeet wrote about this at one point... Anyway the point is, *base 2* numbers have trouble holding decimal precision, and you are likely to get subtle rounding errors. in short, if precision is if decimal important to you, use a base 10 floating point type like `decimal` – TheGeneral Jun 10 '19 at 05:49
  • @TheGeneral Yes, but I thought the results should be consistent across systems and hardware. If it gives -1.490116E-08 on one system and 0 on another, there is something wrong. Maybe this has something to do with the version of .NET framework. – D Navi Jun 10 '19 at 05:55
  • *if decimal precision is important to you* – TheGeneral Jun 10 '19 at 05:55
  • No floating point arrhythmic isn't deterministic in this way – TheGeneral Jun 10 '19 at 05:56
  • .Net core 2.1 and Mono C# compiler version 4.6.2.0 gives 0. ////Compiler version 4.0.30319.17929 for Microsoft (R) .NET Framework 4.5 gives -1,490116E-08. – cdev Jun 10 '19 at 05:59
  • @cdev In my case, I changed target to .NET framework 4 and then to .NET framework 3.5 from Visual Studio project settings and in both cases still got 0 (I didn't change the compiler version). – D Navi Jun 10 '19 at 06:03
  • If you change to 32bit you will probably see the number you expect – TheGeneral Jun 10 '19 at 06:19
  • 64 bit executables seem to return 0, while 32 bit executables show the rounding error. Maybe with 64 bit executables, the cpu uses double precision for calculation internally? But overall, the book is right: Never trust foating point arithmetic accuracy. Even if you get the expected result one time, rounding can occur next time. – Heinz Kessler Jun 10 '19 at 07:20
  • The runtime is entitled to compute this expression with more accuracy than the *float* type can support. Which does happen in practice in 32-bit code, [a processor implementation detail](https://stackoverflow.com/a/14865279/17034). This ugly problem was fixed in more recent processors, the x64 jitter takes advantage of it. Which does not promise more accuracy, less actually, just more consistent results. Getting a seemingly *more* accurate result when the machine computes with a *less* accurate number representation does always give programmers a throbbing headache. It only seems that way – Hans Passant Jun 10 '19 at 14:54

0 Answers0