Why does 'list_to_float' and 'float_to_list' give different results on different versions

Please tell me why the function gives different results on different versions

vsn 19.1 list_to_float(float_to_list(615.4896 / 100, [{decimals, 2}])).

6.16

vsn 24.2 list_to_float(float_to_list(615.4896 / 100, [{decimals, 2}])).

6.15

4 Likes

Different algorithm for rounding. AFAIK the 24.2 is more correct one (cc @DianaOlympos, but from â€śorganoleptic checkâ€ť `6.154` should be rounded to `6.15`, no other decimal points should affect that), but in general it is quite hard topic to have proper rounding of floating points.

5 Likes

Indeed we changed the algorithm to display the pretty print in the shell.
Both are valid, but keep in mind that you are using two different algorithm here to translate a float to a string.

First you translate a string, `615.4896` to a float. Then you translate a string `100` to an integer. You then cast that int to a float, divide the two float, then translate that float to a string at `float_to_list` with the rules of `{decimals, 2}`, which may or may not be correct as they are libc implementation dependant (thanks the C standard), then you translate that string into a float again, with `list_to_float`.

Then you translate that float into a string again by â€śprintingâ€ť to the shell, using a totally different algorithm, which changed in OTP24.

It happens that the new Ryu algorithm used in OTP 24 (and accessible through a BIF option in otp 25) is probably the most â€ścorrectâ€ť for our modern understanding of correctness. But after all these transformations, some of these being destructive of information, it is already a small miracle that you get something that is â€ścorrectâ€ť, for some definitions of â€ścorrectâ€ť.

Defining which round is right in that case depends on the libc, the implementation of the round trip, the precision of the double when it is recasted and the way we chose to round for the pretty printing.

In particular, this does not promise at all that you will get the same result as an output of the pretty print. It is totally possible that the original float and the one that you pretty print after this are different one, due to the way â€śfloatsâ€ť sample the space of reals.

4 Likes