0

I was wondering why precision problems in floating point numbers are different with different values:

#include <iostream>
#include <iomanip>

 int main ()
{
    std::cout << std::setprecision(20);

        double d1(1.0);
        std::cout << d1 << std::endl;

        double d2(0.1);
        std::cout << d2 << std::endl;
        return 0;
  }

The output of this program is:

  1. 1
  2. 0.10000000000000000555

If both the numbers are of type double (that generally have precision problems), why compiler doesn't find any problem with value 1.0 and does find a problem with value 0.1. One more thing that it not clear to me is that if precision is set to 20 digits, why do I get a number that contains 21 digits as the result of d2?

  • 1
    Some numbers can be expressed exactly in binary floating point format, other numbers can only be approximated. Have a read through the [Wikipedia entry](https://en.wikipedia.org/wiki/Floating_point) to see how things work under the hood. –  Jul 15 '15 at 05:22
  • However, when you see `1` and it's a double or float, never assume it's *exactly* 1; always use floating point "logic" when e.g. comparing. –  Jul 15 '15 at 05:24
  • @Evert: You managed to pick one of the two exceptions. _Exactly_ 1.0 and _exactly_ 0.0 do show up unusually often. – MSalters Jul 15 '15 at 08:42
  • @MSAlters True, but it's more a general note of caution; at least I still wouldn't trust 1.0 to be 1.0 if it's printed. I've come across `value == 0.0` comparisons, which were mostly to test whether `value` had been set to something else than its default value. Not sure/curious about cases for `value == 1.0`. –  Jul 15 '15 at 08:49

1 Answers1

2

Your computer uses a representation of floating point in which 1.0 can be stored exactly, but 0.1 can't. This is probably IEC 60559.

Leading zeroes are not considered part of the precision (they are just placeholders); your output does actually have 20 digits not counting the 0. on the start.

M.M
  • 138,810
  • 21
  • 208
  • 365