1

So, today I've got a bit more theoretical question. While studying the floating point types I have written a little test:

#include <iostream>

int main()
{
    float floatTest = 10.0 / 3.0;
    double doubleTest = 10.0 / 3.0;

    const long long ex = 100000000000;

    std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
    std::cout << "float test: " << floatTest * ex << std::endl;
    std::cout << "double test: " << doubleTest * ex << std::endl << std::endl;

    return 0;
}

Results are not really what I expected:

enter image description here

Now, I know that floating point numbers are made from mantissa and exponent, so it would be natural for me that in case of the float type, which by standard guarantees precision up to 7 digits mantissa would be something like 3.333333 and the exponent's value would for example be 37, so I have basically no idea where are these random trash digits coming from. I have also observed one other thing. While there are plenty of these random digits after float loses precision, there is only one random digit after double loss of precision. That's quite weird in my opinion.

Now the question:

Same as in the title, why are there random trash digits in floating point numbers? Is C++ trying to somehow compute the further part of this repeating decimal or is it just the issue with mantissa or is it something else?

I'm literally clueless, where to look for the proper answer. Only thing I have found is IEEE 754 standard, but AFAIK I'd need to buy it if I'd like to read it.

Peter Nimroot
  • 519
  • 5
  • 13
  • 3
    [Google: "IEEE 754 standard PDF", second hit](ftp://ftp.heanet.ie/disk1/openwatcom/devel/docs/ieee-754.pdf) –  Dec 21 '13 at 16:22
  • Also, this is because floating-point numbers don't have infinite precision. If you attempt to print them more precisely than they are, you will get garbage (digits which are basically meaningless and are a result of rounding errors). Furthermore, don't confuse "decimal digits in the fractional part" with significant digits. –  Dec 21 '13 at 16:23
  • My guess is that the behavior is simply undefined. This is C++, so it'll do whatever you tell it too, and if you tell it to print this many digits it will, whether or not the variable has that sort of precision. It's probably quite like going to an undefined index of an array. You can print it... but it'll just print whatever the bits at that memory location are flipped to. – nhgrif Dec 21 '13 at 16:25
  • @nhgrif Do you mean "unspecified"? –  Dec 21 '13 at 16:27
  • 5
    @nhgrif: nope, the situation is more subtle and it's nothing like UB. `operator< – Matteo Italia Dec 21 '13 at 16:27
  • Welp, that's why it was a comment and not an answer. And what kind of programmer would I be if I didn't learn something today? – nhgrif Dec 21 '13 at 16:28
  • @H2CO3 I've been looking for an answer for an hour at least and I haven't found the question you have mentioned, which indeed answers what I asked about. Sorry for duplicate, I'll put more effort into searching next time. Just on a side note are you aware if there are many differences between 1985 and 2008 IEEE 754 document? Besides of that thank you all very much for your comments. – Peter Nimroot Dec 21 '13 at 16:42
  • 1
    @PeterNimroot No problem. The question may not be so easy to search for. As to the standard: I don't *think* that there are a lot of changes between the two, but I'm sure one could find a PDF copy of the 2008 edition digging deeper into Google. –  Dec 21 '13 at 16:44
  • Recently, at my suggestion 'If your question is about small arithmetic or decimal conversion errors, please read the "learn more..." page linked below' was added to the summary for the floating-point tag. I'm curious whether you didn't notice it, or did but the "learn more" didn't answer your question. – Patricia Shanahan Dec 21 '13 at 17:36
  • 1
    "I don't know where it came from" is not the same as "it's random trash". – Pete Becker Dec 22 '13 at 17:51

0 Answers0