The purpose is very simple: we’ve had many cases of people being very confused as to why print() prints two numbers identically but they aren’t equal. Fundamentally the fact that tostring() returns the same string for two different numbers is a bug, while convenient at times.
It’s incorrect to think that previously tostring was somehow able to print clean numbers. That’s not the case, it’s just that by virtue of discarding a couple of bits of precision you would sometimes not see the difference. Consider this program that merrily counts until 54.1 until the error becomes too high and becomes visible:
local r = 0 for i=1,1000 do r += 0.1 print(string.format("%.14g", r)) end
I understand that this may be inconvenient, but I don’t think it makes the current tostring
behavior any less wrong.
Note that after this change, we will guarantee that tonumber(tostring(v))
is equal to v
. This is an important guarantee known as “round-tripping”, and not having this guarantee means that if you try to serialize numbers to a string in text form, you don’t get the same result back which is bad if you ever want to do computations off these numbers. In programming languages, correctness and determinism is important.
You will also find that probably any modern language will have the same behavior as the new behavior of tostring
, eg try printing 1.1-1
in JS, Python, Swift, Rust.