-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fully support IEEE-754 floats on binary matching #4537
Conversation
Here is a quick snippet of what can be done: 1> <<F/float>> = <<16#7FF0000000000000:64>>.
<<127,240,0,0,0,0,0,0>>
2> F.
#Inf
3> float_to_list(F).
"#Inf"
4> is_float(F).
true
5> math:is_finite(F).
false
6> math:is_infinite(F).
true I picked |
@paulo-ferraz-oliveira maybe I misunderstood your question but we don't have a float_to_atom. :) |
@josevalim, you were too fast. I figured my question made no sense and deleted it (I should have edited it, probably), but I still got an answer from you 😄. Great addition, by the way. For history, the (stupid) question was: "Will this work with It goes to show how excited I was/am: my brain just shut down and though "Wouldn't it be nice to have this as an |
At the moment, Erlang does not fully support IEEE-754 encoding in binary matching. In particular, it is not possible to decode/encode infinity, negative infinity, and nan's. Furthermore, all of the arithmetic operations in Erlang raise in the presence of the values above. The IEEE-754 standard makes a strong case for *not* raising when working with non-finite values - but we can probably say this ship has sailed for Erlang. Furthermore, one can assume that, if those features were desired by the community, they would already have been implemented. Therefore, this patch proposes to allow encoding/decoding of non-finite values. After all, if a non-finite value was encoded as part of a binary, it was likely expected that the decoding party should handle it. This pull request adds basic mechanisms to do so. At the same time, this pull request does not change (nor intends to) any of the arithmetic operations. Therefore, operations that raised in the past when returning non-finite values continue to behave the same. A possible venue for exploration in a later pull request is to augment the math module with IEEE compatible functions, for example, `math:ieee_log/1`, `math:ieee_exp/1`, as well as `math:ieee_add/2`, `math:ieee_subtract/2` and so forth (including `math:ieee_negate/1`) that supports non-finite values. This would allow Erlang developers to work with non-finite values only if they want to and allow them to do so efficiently (as currently it is inneficient and cumbersome). I am submitting this pull request for a initial request for comments. In particular, I want to show supporting non-finite values seems to be trivial, given this is handled by any C toolchain that supports IEEE-754 (which is commonplace). I will work on tests if there is interest.
Well I never got why Erlang raised on non-finite values and found it undesirable. That it's not already implement probably doesn't mean it's not desired. So many things to desire so little time ;-) I would say it's worthwhile discussing how such a feature could be implemented possibly in a backward compatible form. Its not only the math functions but also expressions like 1.0/0.0 or over/underflowing (BTW do we have support for -0.0 and +0.0 ?) Raising or non raising should be probably a per process setting, defaulting to raising. |
What was the rationale for the Its none of the choices listed here https://en.wikipedia.org/wiki/NaN#Display |
My guess is the representation would be similar to |
How could I miss this! And one could even have |
I will be happy to have this discussion. For now this PR focuses on the decoding/encoding/checking, exactly because those are backwards compatible. The arithmetic part can be as easy or as hard we want it to be. :D We do have support on -0.0 and 0.0. They were some bugs when handling and printing those, but they have already been fixed on master.
As @wojtekmach said, easy to recognize as a special entity in Erlang. But easy to change to anything else. :) |
Note to self: if we accept this PR, we need to change round/ceil/floor to raise if a non finite float is given (as they expect integer returns). |
I would love to have full IEEE.754 support! However this kind of modification should really extend to other operations such as the behaviour of the division by zero. There should probably be a VM flag to active this change.
I really wish this kind of argument was not used so often. In my experience, in the open source world, a ton of features are highly desired but never implemented for lots of reasons:
Regarding IEEE.754 support in Erlang:
One should not assume that the right solution is the one most similar to the status quo. Floating point operations should definitely not raise. |
Thinking about it, I believe the text representation should match IEEE.754 formats. You were talking about the need to recognize them as "special entities", but contrary to values such as ports or references which are specific to Erlang, non-finite floating point values are not special, they are perfectly valid numerical values. It would be really strange to format strings for a user interface and end up with |
We have to distinguish between external representations which can be produced by
|
I am not sure IEEE 754 actually specifies how Infinity should be exhibited. At least I could not find any reference to the copy of the spec that I own. Most references are actually directly to ∞ (which we could actually use, especially as source codes are now required to be UTF-8). If someone can reference the textual representation of the spec, I would appreciate it. |
Yes I was talking about the external representation. To be precise, it is perfectly fine to use @josevalim Yes, you are right. So it is more about picking what is usually used. I'm used to |
Any news about this one ? I imagine there are lots of things to discuss to one day have full IEEE.754 support in Erlang, but there are some good ideas on this thread. |
I believe the goal is to resume this discussion once OTP 24 is released (this week!!!). :) |
Hi OTP team! Now that OTP 24 is out, I would love to know if you have any feedback on the next steps for this PR or what are the concerns with moving forward with this. Thank you! |
It is in our plans to work with this early on the way to OTP 25. You can
expect activity really soon now.
…On Thu, Jun 3, 2021, 18:39 José Valim ***@***.***> wrote:
Hi OTP team! Now that OTP 24 is out, I would love to know if you have any
feedback on the next steps for this PR or what are the concerns with moving
forward with this. Thank you!
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#4537 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABFWSFIROYZNJLUDVGIS23TQ6V33ANCNFSM4X4IUUTQ>
.
|
Hopefully the following will allow us to drop this code one day: * erlang/otp#4537
We have now discussed this in the OTP team: A short summary before we have a version of the EEP. comparision of ieee floats?Decided to follow ieee total ordering and break backwards compatibility. This is good because we have a standard we can point to, however it is not how most/all other languages compare floats, so it can lead to confusion. How to handle sNaN?sNaN is a special type of NaN that cause x86 (and possibly other) processors to segfault the current program if used. How to indicate that ieee arithmetics is to be used?
Other things to do
It seems to be a lot of work to implement all of this and we questioned if there are other language features that are |
Thank you @KennethL for the summary! 💯 So my understanding is that we will decode them from binaries (with the exception of snan) but the existing operators will continue to raise on non-finite types. Some quick thoughts:
|
Has there been any movement on that front? :) |
The latest input I received was that this would have large ramifications. Returning "infinity" or "nan" might as well be an error for many applications today and doing those changes would make it so it silently works. Therefore there are no plans to move this forward. :) |
I wonder if perhaps having an extra modifier for floats that would unlock this would be possible, something like <<X/float-full:64>> Though I assume the main complexity is in actually having infinities and nan values floating around the codebases, rather than just decoding them. |
Yes, it is having NaN/±inf in Erlang code that is the problem. Specifically it is equality and comparison that is the main hurdle. Now that we have decided that matching -0.0 and +0.0 as the same was a bug, we could make matching a structural comparison and Though problems would still exist, for example if we did It is also a bit odd that It is still a lot of work to fix this in all cases and, as Jose mentions, there is code where So no, there are currently no plans to revisit this. |
At the moment, Erlang does not fully support IEEE-754
encoding in binary matching. In particular, it is not
possible to decode/encode infinity, negative infinity,
and nan's.
Furthermore, all of the arithmetic operations in Erlang
raise in the presence of the values above.
The IEEE-754 standard makes a strong case for not
raising when working with non-finite values - but we can
probably say this ship has sailed for Erlang. Furthermore,
one can assume that, if those features were desired by
the community, they would already have been implemented.
Therefore, this patch proposes to allow encoding/decoding
of non-finite values. After all, if a non-finite value was
encoded as part of a binary, it was likely expected that
the decoding party should handle it. This pull request adds
basic mechanisms to do so.
At the same time, this pull request does not change
(nor intends to) any of the arithmetic operations. Therefore,
operations that raised in the past when returning non-finite
values continue to behave the same.
A possible venue for exploration in a later pull request
is to augment the math module with IEEE compatible functions,
for example,
math:ieee_log/1
,math:ieee_exp/1
, as well asmath:ieee_add/2
,math:ieee_subtract/2
and so forth(including
math:ieee_negate/1
) that supports non-finitevalues. This would allow Erlang developers to work with
non-finite values if they want to and allow them to do so
efficiently (currently it is inefficient and cumbersome).
I am submitting this pull request for a initial request for
comments. In particular, I want to show supporting non-finite
values seems to be trivial, given this is handled by any C
toolchain that supports IEEE-754 (which is commonplace).
I will work on tests if there is interest.