Live data from Hacker News

0.1 and 0.2 Returns 0.30000000000000004 (2018)

qntm.org

21–30 of 161 posts

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#21
post #17
post #11

Earlier quoted context omitted.

Floating point is fine. Non-integers are inherently tricky to represent, especially when you have to pack it into 32 bits. You could maybe quibble with some of the decisions around NaN and denormals and things like that, but mostly IEEE-754 got it right. There's a reason it's been the standard for three and a half decades now, and it's served the computer industry very well. Incidentally: the fact that 0.1+0.2 does n…

Of course it shouldn't be base 10. It should be base 60. That has more prime factors and wastes fewer bits than BCD does.

Or base 256 so that it fits a byte efficiently. Oh... wait...

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#22
post #4

Not in Raku it doesn't! > 1.1 + 2.2 3.3 > 1.1 + 2.2 == 3.3 True EDIT: to be clear: this is not because Raku is magic, it's because Raku defaults to a rational number type for decimal literals, which is arguably a much better choice for a language like Raku.

Because that syntax in raku uses rational type, which fails for many other uses, and by using the syntax most languages use for a floating type, makes it harder to spot these issues, just like here. For example,

    0.1e0 + 0.2e0 
yields 0.30000000000000004. Your example also fails

    1.1e0 + 2.2e0 == 3.3e0
returns false.

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#24
post #13
post #4

Not in Raku it doesn't! > 1.1 + 2.2 3.3 > 1.1 + 2.2 == 3.3 True EDIT: to be clear: this is not because Raku is magic, it's because Raku defaults to a rational number type for decimal literals, which is arguably a much better choice for a language like Raku.

Ahem, this is about 0.1 + 0.2. I think Raku also uses IEEE 754 double precision floating point numbers for the Num type, no? Edit: it seems that Raku uses rationals as a default [1], so it doesn't suffer from the same problem by default. [1]: https://0.30000000000000004.com/#raku

Oh, missed that, it's usually 1.1 + 2.2 in these kinds of discussions.

Yeah, exactly, Raku defaults to a rational number type for these kinds of numbers. I honestly think that is a perfectly fine way to do it, you're not using Raku for high performance stuff anyway. It's not so different from how Python will start to use arbitrarily sized integers if it feels it needs to.

Raku by default will convert it to a float if the denominator gets larger than a 64-bit int, but there's actually a current pull request active that lets you customize that behavior to always keep it as a Rat.

Really interesting language, Raku!

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#25
Does this mean I could write a calculator in JavaScript which is more accurate than the language but not as fast?

For example: just treat numbers as strings and write code that adds the digits one by one and does the right carries

Now that I think about it, is this the whole point of the Java BigDecimal class?

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#27

I've seen a lot of stuff on getting the shortest representation that is equal to the floating point value back but what about finding the minimum/maximum representation that is equal to a given value?

That's a rather easier problem in comparison. Just use the nextafter function in the standard library to figure out the next representable number. Then try not to exceed half of the difference using string processing.

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#28
post #4

Not in Raku it doesn't! > 1.1 + 2.2 3.3 > 1.1 + 2.2 == 3.3 True EDIT: to be clear: this is not because Raku is magic, it's because Raku defaults to a rational number type for decimal literals, which is arguably a much better choice for a language like Raku.

Because that syntax in raku uses rational type, which fails for many other uses, and by using the syntax most languages use for a floating type, makes it harder to spot these issues, just like here. For example, 0.1e0 + 0.2e0 yields 0.30000000000000004. Your example also fails 1.1e0 + 2.2e0 == 3.3e0 returns false.

I mean, yeah, if you force the numbers to be floats, then of course it's going to fail. I personally think Raku's way of defaulting to floats is the better way to go for a scripting language like this, and I disagree that "it fails for many other uses". It works just fine (like, it doesn't break if you pass it to sqrt() or whatever), it's just less performant. It's the exact same kind of tradeoff that Python's implicit promotion to big integers make.

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#29

Does this mean I could write a calculator in JavaScript which is more accurate than the language but not as fast? For example: just treat numbers as strings and write code that adds the digits one by one and does the right carries Now that I think about it, is this the whole point of the Java BigDecimal class?

Yes, and it would be inexcusable malpractice to implement a calculator using the native floating-point type.

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#30

Indeed, and therefore: 0.1 + 0.2 != 0.3 You can check it in the JavaScript console. This actually makes me wonder if anyone's ever attempted a floating-point representation that builds in an error range , and correctly propagated/amplified error over operations. E.g. a simple operation like "1 / 10" (to generate 0.1) would be stored not as a single floating-point value, but really as the range between the closest rep…

But what you would actually get is something like this:

   x---0.1 + 0.2 ---x
      x---0.3---x
That is, the range of 0.1 + 0.2 would be wider than the range of 0.3. And now what do you do? There is overlap, so are they equal? But there are parts that don't overlap, so are they different?
Post reply on HN