Why does 0.1 + 0.2 = 0.30000000000000004?

Why does 0.1 + 0.2 = 0.30000000000000004?

Julia Evans
@b0rk I thought it equaled “0.10.2” 😂
@Agracey @b0rk It's a normal programing not javascript

@b0rk a) cool deep dive & explainer

b) I wish there was at least a passing mention that it doesn't need to be that way, or that it isn't that way in all languages.

@b0rk I don’t have to think about floating point maths any more and you can’t make me 😜

@antinomy @b0rk Kate: in the recent payment app i worked on we just avoided the problem by doing everything in pennies. ;)

I am also fully on board with the whole "please don't make me deal with floating point BS" sentiment.

@b0rk I can only think of two reasons
@b0rk Because you're using the wrong math package! :)
@b0rk Thanks for not just making a fun fact out of but explaining this in detail!
@b0rk It's not that way everywhere.

@b0rk FWIW I'd note:

1/10 in binary is a non-terminating:
0x1.999999999999999.....* 2^-4

so it must be rounded to fit in a finite number of digits. (2/10 is just twice that). Add these two rounded things together and you get something different than if you "symbolically" worked it out on paper. This isn't a "binary" problem it's a finite digits one. If working with a decimal floating point you'd hit the same "problem"...say with 1/3 + 2/3.

@b0rk My favorite site on this is https://0.30000000000000004.com/ . But mostly because of the domain name.
Floating Point Math

@soaproot @b0rk

Oh good, wanted to make sure someone had posted that site!

@b0rk I love your work so much … my son is a CS student, and I find myself sharing your stuff all the time (including this one, just now), because it’s so clear and concise. Thank you for all of it! For myself and my son 😀
@b0rk This is also covered in the official Python FAQ and its tutorial: https://docs.python.org/3/faq/design.html#why-are-floating-point-calculations-so-inaccurate
デザインと歴史 FAQ

目次: デザインと歴史 FAQ- Python はなぜ文のグループ化にインデントを使うのですか?, なぜ単純な算術演算が奇妙な結果になるのですか?, なぜ浮動小数点数の計算はこんなに不正確なんですか?, なぜ Python の文字列はイミュータブルなのですか?, なぜメソッドの定義や呼び出しにおいて 'self' を明示しなければならないのですか?, 式中で代入ができないのはなぜですか?, ...

Python documentation

@b0rk Nice. Too many summaries of floating point cover the mechanical structure, but not operations on them. (We'll "skip the witches" of the Quake algorithm for now…)

It's not tensegrity (I may watch too many civil engineering channels) but this structural summary and overview/explanation of limitations came up recently in my recommended.

https://www.youtube.com/watch?v=Oo89kOv9pVk

Financial values?
Don't. Just… just don't.

This means JSON is fundamentally not suited to financials.

Example:

Floating Point Numbers, Odd Behaviour and What You Should Really Know (Data Structures & Algorithms)

YouTube
@b0rk Adding 0.1 to itself 10 times and getting 0.9̄8 is always a fun, fast, hilarious demo.
@b0rk yay floating points!!!

@b0rk

from a unit test:

// dang double precision
EXPECT_EQ(0.30000000000000004), Interpolate(range, 0.75));

@b0rk Just had to write a nice unit test for basic math. Turns out it's more broken than I expected.

https://godbolt.org/z/8KWzc5W3o

Compiler Explorer - C++

int main() { double sum = 0; for (size_t n = 0; n < 10; n++) { sum += 0.1; } printf("%s\n", (10 * 0.1 == 1) ? "math works" : "math fails"); printf("%s\n", (10 * 0.1 == sum) ? "math works" : "math fails"); }

@dascandy42 @b0rk Isn't because ICC and ICX by default enables -ffast-math?
@b0rk Ancient but still good:
What every computer scientist should know about floating point arithmetic
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
What Every Computer Scientist Should Know About Floating-Point Arithmetic

@b0rk the short answer is that floating point numbers on a computer should ALWAYS be treated as an approximation of “real world” numbers. Because that’s what they are.
@b0rk @siracusa I read this in my rss reader this morning and 🤯
@b0rk Python's decimal module is a great way to see the full decimal expansion of floats. It's much nicer than asking for too many digits and ending up with lots of trailing zeros

@b0rk this reminds me of rounding numbers in JavaScript. Needing to Math.Round(3.5) I’d expect it to be 4, but you have to multiply by 100 and divide by 100. On paper it’s the same, but float numbers are fun. This actually helps explain this kid of situation now!

Math.round(total * 100) / 100

@b0rk the actual rounding modes in floating point are quite interesting. FP addition for instance is calculated to a few additional bits. For round-to-nearest-even the value is truncated and then a decision is made whether to add one to the result using the final bit, first discarded bit and the OR of the remaining bits: If the first discarded bit is 1 then... ok, prose is no good. Take this diagram:
@b0rk rember this from times with 16-bit int and the performance hit for floating point calculations. C code with short int, int and long int and migrations from 32-bit to 64-bit int as default that crasched programs.
@b0rk If I could quote, I would. A fun one for @Mathstodon.xyz

@b0rk wonderful post! I always struggle to explain that. Now I can point learners to your post.

Would it make sense for you to add a small mention of Python's Decimal class in the standard library as a possible workaround in certain situations?

@villares @b0rk IBM solved this on architecture level by implementing a low level Decimal Binary floating point where the operations are done on "decimal" instead of "binary". Ensure the precision, but there's an obvious storage and memory cost
@b0rk many years ago I worked on a JS system that the PHP developers didn’t want to use as on PHP the floating point errors are usually ignored/avoided. Thanks for pointing that out on the article, a gazillion memories came back on that subject.

@b0rk I very recently saw an online homework marking system that marked an exactly correct answer "0.000" wrong. It was expecting 4.523e-16 O.o

This lead me to find this interesting paper:
Toronto and McCarthy, ‘Practically Accurate Floating-Point Math’. "With the right tools, floating-point code can be debugged like any other code, drastically improving its
accuracy and reliability."

Investgates the "badlands" of some FP functions.
Downloadable here e.g. https://jeapostrophe.github.io/home/static/tm-cise2014.pdf