5

In many programming languages operations like 0.1 + 0.2 won't equal 0.3, but rather 0.30000000000000004. And thus, checks like 0.1+0.2 == 0.3 will return false.

As far as I am concerned, this is due to IEE 754 standard and that's why it is common for many languages.

The same behaviour can be found in C#. I used next code snippet to test it:

static void Main(string[] args)
    {
        double x = 0.2;
        double y = 0.1;
        double res = 0.3;
        double z = x + y;

        Console.WriteLine("bool result = {0}", z == res); // outputs false
        Console.ReadLine();
    }

but if I am using the same code but with float variables everything works in other way:

static void Main(string[] args)
    {
        float x = 0.2f;
        float y = 0.1f;
        float res = 0.3f;
        float z = x + y;

        Console.WriteLine("bool result = {0}", z == res); // outputs true
        Console.ReadLine();
    }

Can anyone explain it to me?

volk
  • 762
  • 1
  • 6
  • 19
  • 3
    Speaking generally, you should rather do a `Math.Abs(xf - yf) < TOLERANCEf` to determine equality for floating point values ... –  May 18 '16 at 15:21
  • 15
    I think this is the first time I've heard someone ask to explain why it _does_ work. – D Stanley May 18 '16 at 15:24
  • 1
    Read [this.](http://stackoverflow.com/a/15117741/767890) – InBetween May 18 '16 at 15:25
  • You just got lucky. Try some other numbers. Or the optimizer just replaced the addition with a constant. – Eugene Sh. May 18 '16 at 15:25
  • 2
    A typical programmer where one of the two: "_It doesn't work and I have no idea why_" or "_it works and I have no idea why_" – Khalil Khalaf May 18 '16 at 15:26
  • None of the duplicates answer this particular question. – Andrey May 18 '16 at 15:26
  • @Andrey Not true, the highest rated answer to the duplicate I voted answers *exactly* this question. – InBetween May 18 '16 at 15:27
  • 6
    I don't understand why it was marked as duplicate - it is not. – Evk May 18 '16 at 15:27
  • Just to add, try running your program on `Release` mode and you might get the result = `False`. this depends on machine to machine as well as Debug to Release mode. – Habib May 18 '16 at 15:28
  • 5
    @Evk Because the answer to the second duplicate certainly answers this one and it really isn't useful to repeat it here. – MicroVirus May 18 '16 at 15:28
  • 1
    @Evk This is the answer which would have to be duplicated in order to answer this question: http://stackoverflow.com/a/753955/1871033 – CherryDT May 18 '16 at 15:29
  • I've voted to reopen as I *think* this is as much to do with compile time evaluable constant expressions (which *might* be wider than an IEEE754 floating point double - but maybe not in C# - I don't know), as much as floating point operations themselves. But I'm not a C# expert. By the way, comparing two numbers with a linear `abs` difference with a tolerance as a rule of thumb is total hogwash. – Bathsheba May 18 '16 at 15:31
  • Well if dig enough to the _second_ duplicate, you indeed might find an answer to this question (or become even more confused). But at least first duplicate is not related - this question is not about why floating point operations are not precise. – Evk May 18 '16 at 15:32
  • 3
    @Bathsheba compile time evaluation is definitely covered by one of the duplicated questions (by Eric Lippert). Comparint abs with tolerance is the best practice not sure why you call it hogwash. – Andrey May 18 '16 at 15:33
  • @Evk, it was first one which has an [answer](http://stackoverflow.com/a/753955/1997232) explaining in details why it's imprecise (which should lead you to understanding, why it *sometimes* precies). – Sinatr May 18 '16 at 15:34
  • @MicroVirus the answer to the second duplicate just states that "(.1f+.2f).Equals(.3f) == true" just happens to be so by pure luck and that's it Which is true but one could dig deeper and figure out what kind of factors lead to it in a given context. – Andrey May 18 '16 at 15:35
  • To clear up the confusion, the *actual* answer to this question is given by Eric Lippert here: [(.1f+.2f==.3f) != (.1f+.2f).Equals(.3f) Why?](http://stackoverflow.com/a/15117741/3764814) – Lucas Trzesniewski May 18 '16 at 15:37
  • 1
    http://stackoverflow.com/a/14865279/17034 – Hans Passant May 18 '16 at 16:03
  • 2
    My answer in the duplicated question covers the question asked here: why is it that going to *lower precision* sometimes *increases accuracy*? – Eric Lippert May 18 '16 at 16:11
  • @Andrey et al. here's a good starting reference: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ – Bathsheba May 18 '16 at 17:57

0 Answers0