I still remember when I encountered this and nobody else in the office knew about it either. We speculated about broken CPUs and compilers until somebody found a newsgroup post that explained everything. Makes me wonder why we haven't switched to a better floating point model in the last decades. It will probably be slower but a lot of problems could be avoided.
0.30000000000000004
31–40 of 422 posts
Re: 0.30000000000000004
#32I remember in college when we learned about this and I had the thought, "Why don't we just store the numerator and denominator?", and threw together a little C++ class complete with (then novel, to me) operator-overloads, which implemented the concept. I felt very proud of myself. Then years later I learned that it's a thing people actually use: https://en.wikipedia.org/wiki/Rational_data_type
Re: 0.30000000000000004
#33 printf("%.4g", 1.125e10) --> 1.125e+10
printf("%.4f", 1.125e10) --> 11250000000.0000Re: 0.30000000000000004
#34I still remember when I encountered this and nobody else in the office knew about it either. We speculated about broken CPUs and compilers until somebody found a newsgroup post that explained everything. Makes me wonder why we haven't switched to a better floating point model in the last decades. It will probably be slower but a lot of problems could be avoided.
Unless you have a floating point model that supports arbitrary bases, you're always going to have the issue. Binary floats are unable to represent 1/10 just as decimal floats are unable to represent 1/3. And in case anyone's wondering about handling it by representing the repeating digits instead, here's the decimal representation of 1/12345 using repeating digits: 0.0[000810044552450384771162413932766302146618063993…
See also binary coded decimals.
Re: 0.30000000000000004
#35It used to be widespread because floating point processors were rare and any floating point computation was costly.
That's not longer the case and everyone seems to immediately use floating point arithmetic without being fully aware of the limitations and/or without considering the precision needed.
Re: 0.30000000000000004
#36The explanation then goes on to be very complex. e.g. "it can only express fractions that use a prime factor of the base".
Please don't say things like this when explaining things to people, it makes them feel stupid if it doesn't click with the first explanation.
I suggest instead "It's actually rather interesting".
Re: 0.30000000000000004
#37This is a good thing to be aware of. Also the "field" of floating point numbers is not commutative†, (can run on JS console:) x=0;for (let i=0; i --> 1.000000000000001 x=1;for (let i=0; i --> 1 Although most of the time a+b===b+a can be relied on. And for most of the stuff we do on the web it's fine!†† † edit: Please s/commutative/associative/, thanks for the comments below. †† edit: that's wrong! Replace with (a+b)+…
1.0 + 1e-16 == 1e-16 + 1.0 == 1.0 as well as 1.0 + 1e-15 == 1e-15 + 1.0 == 1.000000000000001
however (1.0 + (1e-16 + 1e-16)) == 1.0 + 2e-16 == 1.0000000000000002, whereas ((1.0 + 1e-16) + 1e-16) == 1.0 + 1e-16 == 1.0
Re: 0.30000000000000004
#38This is a good thing to be aware of. Also the "field" of floating point numbers is not commutative†, (can run on JS console:) x=0;for (let i=0; i --> 1.000000000000001 x=1;for (let i=0; i --> 1 Although most of the time a+b===b+a can be relied on. And for most of the stuff we do on the web it's fine!†† † edit: Please s/commutative/associative/, thanks for the comments below. †† edit: that's wrong! Replace with (a+b)+…
> Also the "field" of floating point numbers is not commutative, (can run on JS console:) OK. >> x = 0; 0 >> for (let i=0; i > x + 1 1.000000000000001 >> 1 + x 1.000000000000001 You've identified a problem, but it isn't that addition is noncommutative.
Re: 0.30000000000000004
#39Re: 0.30000000000000004
#40I remember in college when we learned about this and I had the thought, "Why don't we just store the numerator and denominator?", and threw together a little C++ class complete with (then novel, to me) operator-overloads, which implemented the concept. I felt very proud of myself. Then years later I learned that it's a thing people actually use: https://en.wikipedia.org/wiki/Rational_data_type
Reminds me of this Inigo Quilez article on experimenting with rendering using rational numbers: https://iquilezles.org/www/articles/floatingbar/floatingbar....
And then of course there have been several other "x.abs() < 0.01" cases for various purposes. So I could definitely see that being an interesting experiment.