Closed OTP-Maintainer closed 3 years ago
sverker
said:
This problem stems from the questionable design "choice" to make {{0.0 =:= -0.0}}.
I don't think it's directly caused by list/binary_to_float by rather the compiler doing some sort of constant folding optimization which changes 0.0 to -0.0 as they are "the same".
sebastian
said:
The byte code shows that the NIFs were evaluated properly at compile-time, corroborating your suggestion that the bug is in the compiler.
Unfortunately, the byte code loads two +0.0 for calling {{f/2}}, but {{f/2}} chokes on a bad +0.0, not on the -0.0. So there must be some monkey business going on with the constants themselves.
lukas
said:
I think that the only sane thing that we can do is to forbid -0.0 completely as we do with NAN and INF. This would effect binary_to_float, binary_to_term and <<F/float>>. However this breaks backwards compatibility, which may not be ok.
Other options are:
* Auto convert -0.0 to 0.0 at ingress points.
** This approach works pretty well but creates some strange scenarios, similar to what you have seen:
{noformat}
<<F1/float>> = B1 = <<1:1,0:63>>, %% F1 is auto converted from -0.0 to 0.0.
B2 = <<F1/float>>, %% B2 now gets the +0.0 representation
false = B1 == B2.
{noformat}
* Make the compiler not use normal equivalence, but instead use a special equivalence where -0.0 =/= 0.0.
** Using a special equal is error prone and slow.
* Don't allow the compiler to evaluate in compile time binary_to_float, list_to_float or <<F/float>> matches.
** Solves the problem for this specific problem, but there may be more and this doesn't make the language as such more consistent.
Anyone that has other opinions feel free to chime in.
sverker
said:
We don't see any way to "fix" this, without breaking some sort of backward compatibility, as in Erlang as well as many other languages +0.0 and -0.0 compare (match) as equal.
Original reporter:
sebastian
Affected version:Not Specified
Component:kernel
Migrated from: https://bugs.erlang.org/browse/ERL-642