Live data from Hacker News

0.1 and 0.2 Returns 0.30000000000000004 (2018)

qntm.org

51–60 of 161 posts

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#51

In python, 0.3 prints as 0.3, but it's a double, so it should be 0.299999999999999988897769753748434595763683319091796875 (according to the article, and the 0.1+0.2 != 0.3 trick also works) What controls this rounding? e.g., in an interactive python prompt i get: >>> b = 0.299999999999999988897769753748434595763683319091796875 >>> b 0.3

It depends on how many decimal places you are printing

    >>> f'{b:.54f}'
    0.299999999999999988897769753748434595763683319091796875
    >>> f'{x:.16g}'
    0.3
    >>> f'{x:.17g}'
    0.29999999999999999

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#52

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…

Interval arithmetic is what you're looking for, and there's an IEEE standard and many implementations.

Thank you!!

Yes, that turns out to be exactly it [1]. Looks like there's even at least one JavaScript library for it [2].

It seems like such a useful and intuitive idea I have to wonder why it isn't a primitive in any of the common programming languages.

[1] https://en.wikipedia.org/wiki/Interval_arithmetic

[2] https://github.com/mauriciopoppe/interval-arithmetic

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#53
post #42

Earlier quoted context omitted.

That sounds interesting, but I would imagine it would become very complicated once you start applying nontrivial functions (discontinuous functions, for example). In that case the range of possible values could actually become discontinuous. I would imagine accounting for that is actually more computationally expensive than just using arbitrary precision decimals.

Yeah, you call tan() on that number, and suddenly your interval is like most of the number line. Actually, you don't even have to be that fancy: if the number is close to epsilon, the error bars on 1/x would be huge.

But isn't that a feature, rather than a bug? It prevents you from getting "false accuracy".

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#54
post #2

Floating point considered harmful Edit: this is not a blanket statement. It was meant in the context.

Not at all. For all it's faults, floating point is incredibly fast. It's not some convenience hack that we lazy programmers have come up with, it's an incredibly quick way to do numerical computation. It will always have it's place (sometimes even in finance to represent money, to many people's shock).

To add to that, in modern processors FP calculation is faster than integer calculation, both in terms of latency and throughput (as long as you don't hit subnormal numbers). This is very unintuitive and mostly due to disproportional demands.

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#55
Related past threads (not about this article):

0.30000000000000004 - https://news.ycombinator.com/item?id=21686264 - Dec 2019 (402 comments)

0.30000000000000004 - https://news.ycombinator.com/item?id=14018450 - April 2017 (130 comments)

0.30000000000000004 - https://news.ycombinator.com/item?id=10558871 - Nov 2015 (240 comments)

0.30000000000000004 - https://news.ycombinator.com/item?id=1846926 - Oct 2010 (128 comments)

Resisting temptation to list floating-point math threads because there are so many:

https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#56
post #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.

Ah "nextafter" is indeed what I was looking for it just isn't in the JS standard library or Python version I use. Google has plenty examples of the function once you know what it's called though.

Complexity wise that actually seems to give an equally simple "shortest answer" method - nextafter up and down and using text processing find the first digit that changes, see if it can be zero, if not choose the lowest value it can be an increment by one, remove the rest of the string accordingly, and right trim any 0s from the resulting.

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#57

In python, 0.3 prints as 0.3, but it's a double, so it should be 0.299999999999999988897769753748434595763683319091796875 (according to the article, and the 0.1+0.2 != 0.3 trick also works) What controls this rounding? e.g., in an interactive python prompt i get: >>> b = 0.299999999999999988897769753748434595763683319091796875 >>> b 0.3

It is the shortest decimal number that converts back to that exact FP number. There are tons of complex algorithms for that [1].

[1] See my past comment for the overview: https://news.ycombinator.com/item?id=26054079

Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)

#58

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?

Well right now you basically can't ever check for equality with floating-point arithmetic and trust that two numbers that should intuitively be equal are reported as equal.

For me, floating-point equality would be if there are any parts that overlap. Basically "=" would mean "to the extent of the floating-point accuracy of this system, these values could be equal".

If you're doing a reasonably limited number of operations with values reasonably larger than the error range, then it would meet a lot of purposes -- you can add 0.5 somewhere in your code, subtract 0.5 elsewhere, and still rely on the value being equal to the original.

Post reply on HN