3 ms·
anyone understand why is it 0.30000000000000004, why not 0.30000000000000002 or 0.30000000000000003 or something else?
by GnwbZHiU 11y ago
anyone understand why is it 0.30000000000000004, why not 0.30000000000000002 or 0.30000000000000003 or something else?
- Piskvorrr 11y agoIt's the closest binary representation. See e.g. this: https://www.reddit.com/r/javascript/comments/2scikz/eli5_why_is_this_true_01_02_030000000000000004/cnpkaug https://www.reddit.com/r/javascript/comments/2scikz/eli5_why...
- dbaupp 11y agoFloating point is (usually) about "closest representable value". That is, the normal floats form a finite subset of the real numbers, and a calculation like x + y will pick the closest element to the true result. In this case, adding the closest floating point value to "0.1" (0x1999999999999a / 2^56) and the closest one to "0.2" (0x1999999999999a / 2^55) gives 0x13333333333334 / 2^54 which is exactly 0.3000000000000000444089209850062616169452667236328125 (Rational numbers with a denominator that's a power of two have a finite decimal representation, and that's the full one for this number.) However, when printing, one is either interested in a close-enough rounded value (e.g. like some languages print 0.3 by default, or how %.3f will explicitly limit to 3 digits), or an exact representation. The exact representation should be round-trippable, so when you read it back in, you get exactly the same value. In practice this means printing a float z as a decimal value such that the closest float to the exact decimal value (i.e. as a real number) is z. Obviously the full string above works because it is exact, but it is nice to be as short as possible. In this case, the floats immediately before and after our number are exactly 0.299999999999999988897769753748434595763683319091796875 0.300000000000000099920072216264088638126850128173828125 So, only printing up to the first 4 is enough to uniquely identify our float: it is the closest one. The 0.2999* float is slightly interesting: it is the closest float to 0.3, and most environments will print "0.3" in exact mode. There's a lot of trickery/research around printing[1] and operating on floats: rounding things correctly can be highly non-trivial[2]. [1]: e.g. http://www.cs.indiana.edu/~dyb/pubs/FP-Printing-PLDI96.pdf http://www.cs.indiana.edu/~dyb/pubs/FP-Printing-PLDI96.pdf [2]: https://en.wikipedia.org/wiki/Rounding#Table-maker.27s_dilemma https://en.wikipedia.org/wiki/Rounding#Table-maker.27s_dilem...