7

Consider this code:

double d = 9000000000000000000d;
while (d == 9000000000000000000d)
{
   d += 500;
   Console.WriteLine(d);
}

Why does the code run into an infinite loop?

Why doesn't the compiler throw any exception?

MrTux
  • 32,350
  • 30
  • 109
  • 146
  • 18
    Double can store 15 significant digits. Adding 500 thus simply cannot change the value. Something the debugger can easily show you. – Hans Passant Dec 19 '15 at 17:12
  • Can you show the output of `Console.WriteLine`? just curios... – René Vogt Dec 19 '15 at 17:13
  • 1
    @RenéVogt Console.WriteLine prints 9E+18 – Camilo Terevinto Dec 19 '15 at 17:14
  • 18
    Why would a compiler *ever* throw an exception? – harold Dec 19 '15 at 17:17
  • 1
    Interestingly enough, if you had chosen `d += 513;` or anything bigger than that, you wouldn't have realized of this as the loop stops exactly after the first time – Camilo Terevinto Dec 19 '15 at 17:17
  • You can also consider using `System.Numerics.BigInteger` if you need greater precision than what `decimal` provides. – drf Dec 19 '15 at 17:17
  • 1
    Compilers don't throw exceptions. And it doesn't produce an error because this is a runtime problem. If there should be an exception at runtime would be an interesting discussion. I think there is nothing really exceptional to this situation. Floating point computations have a lot of pitfalls developers should be aware of. – René Vogt Dec 19 '15 at 17:19
  • 3
    `Why compiler doesn't thrown exception?` Why should it? That's how floating point numbers work and how those are defined. – MrTux Dec 19 '15 at 17:21

1 Answers1

18

A double has a varying precision, i.e. a fixed number of significant bits.

A double/float number (floating point number) consists of an exponent and a mantisse (cf. the IEEE754 standard). The logic bebind this is that with larger numbers one doesn't need a high precision for small numbers, whereas for small numbers one needs a high precision. So, it might happen that d==d+1 is true as +1 does nothing for large numbers (That's also a reason why one should not use floating point numbers for representing money; also comparing floating point numbers is problematic as 4*0.1!=0.4 might be true, depending on the implementation and possible rounding errors). This is defined in the IEEE754 standard and, thus, won't throw any exception (btw. compilers can issue warning or errors, but don't throw any exceptions).

That's in contrast to integers which always have a precision of 1. So, if you need to handle large numbers with a precision of 1, you need to consider to use BigInteger implementations or use decimal with a fixed set of decimal digits and guaranteed precision.

MrTux
  • 32,350
  • 30
  • 109
  • 146