Live data from Hacker News

In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

erlangforums.com

51–60 of 236 posts

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#51
post #5

This feels like a bad idea. Treating +0 and -0 as unequal because they have different bit patterns is no more correct than treating two NaNs as equal because they have the same bit pattern. Zero is zero.

In case of floating points, since they are an approximation, zero is not zero. Zero is a quantity approaching to zero. In fact dividing by zero with floats is entirely possible! (it leads to infinite, positive or negative depending on the sign). For example, the quantity (try it in Python): 0.1 ** 100 / 1000**100 evaluates to 0.0 while the quantity 0.1 ** 100 / (-1000**100) evaluates to -0.0 It's clear that neither t…

That sounds wrong to me. In IEEE floating point, 0.0 is not an approximation of zero, it is zero exactly. The binary value is literally all zero bits. Negative zero appears simply from the IEEE floating point format reserving a bit for the sign.

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#52
post #3

As a general rule, if you find yourself comparing floating point numbers, that's probably not what you want. I'm wondering what they are going to do with other operators, >=, <= etc

It is 2023 and our tooling still encourages the same mistakes people were making 40 years ago. Can we really not have equality operators that do a comparison with a 1% tolerance or something as a sensible default equivalence instead of blatantly wrong bitwise comparison? I would even be happy with a default set of compiler warnings or errors, which I don’t believe I have ever seen.

From a user POV, I think == and === on floats should simply be undefined in any language. It should be a compile time or runtime error.

There can be a separate function `float_equals()` with explicit args that does what people want

The only reason to use the same syntax == is for POLYMORPHIC code that is actually correct.

But it's not going to be correct with floats, because they don't obey the same algebraic laws ... So the syntax should be different!

---

I believe the Erlang compiler optimization presented as justification for this change is a good example

The compiler wants to reason about code, independent of types

But that reasoning about the =:= operator is wrong for the float case.

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#53
post #25

Earlier quoted context omitted.

This is specifically about equality. Comparing FPs for equality is very risky, as your numbers can differ by 0.00000000000001 without anyone noticing. Strict inequality (> and <) comparison are generally fine as long as you avoid NaNs.

Ok, sure, so it was just for a specific case of comparison. Well, followup, if some error Epsilon can be introduced during any manipulations, when you check for strict inequalities do you check x < y + Epsilon? Does the language implicitly do it for you?

The language just gives you the direct comparison.

If you know numerics, then you can come up with the correct value for epsilon. But that is hard work. There are various things that the language could do for you, like use a dynamic amount of precision, or interval arithmetic where the error bounds are saved—but! Most of the time people just want the answer faster and with less memory used, which is what you get with bare floats. The people who make it their job to care about numerical accuracy can do it better than the language runtime would anyway.

Most of the problems are more easily solvable at a higher level anyway. Like, imagine Clippy saying to you, “It looks like you’re inverting a matrix. Are you sure that’s a good idea?”

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#54
There is a huge misconception here which really should be clarified in the title. Erlang has an "exactly equal" or strict equality operator, called =:=, which is different from just usual equality, which is ==. The usual equality operator will keep having +0.0 = -0.0, and floating point arithmetic will keep behaving as you would expect... It's that we no longer have +0.0 =:= -0.0, which is a very different thing (and frankly, makes sense - there should be some special operator that can differentiate between these two values).

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#55

Earlier quoted context omitted.

It is 2023 and our tooling still encourages the same mistakes people were making 40 years ago. Can we really not have equality operators that do a comparison with a 1% tolerance or something as a sensible default equivalence instead of blatantly wrong bitwise comparison? I would even be happy with a default set of compiler warnings or errors, which I don’t believe I have ever seen.

The problem with defining an “epsilon” (1% in your case) is that there is no value that would please everyone. For some, 1% will be fine, but others may need 0.0001%. The solution is to either use decimal floats if they suit your need (and eat the performance penalty), or to use a linter that flags float comparisons by equality.

And then there's the question of how you use the epsilon - i.e. whether 1.2e-16 and 1e-20 are "within 1%". Sometimes those are very much different sizes, but if you're comparing sin(π) (i.e. the 1.2e-16) with some other almost-zero computation, they're very much within 1%.

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#56
As someone who programmed assembly on a one's complement machine* 40 years ago, this discussion is interesting, from both the "haven't we learned anything" and the "makes sense to me" camps.

More interesting to me is how they are introducing this change, both in the previous OTP and next, and how they will arm people with tools to hopefully identify and understand the impact. I wonder how many folks will actually be impacted?

* Sperry Univac 1100/62

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#57
post #3

As a general rule, if you find yourself comparing floating point numbers, that's probably not what you want. I'm wondering what they are going to do with other operators, >=, <= etc

I'm assuming you mean equality comparison, rather than comparison in general! but is there a better algebraic structure to use when thinking of floats? like, in terms of limits, or something that tracks significant digits and uncertainty? how do formal methods handle these?

There's more than one way to skin that cat, but interval arithmetic is a good and simple model. You can take the part of the real line which maps to the single float you are thinking about, and then look at the image of that set under the whatever functions you are thinking about.

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#58
post #30

Earlier quoted context omitted.

Are there even any applications where one needs a) decimal precision and b) fast computation? Financial calculations don't need to be fast.

Algorithmic trading, of course. High-frequency trading in particular. But any trading, in fact, when you run simulations for thousands of instruments and search among millions of parameters. Or when you implement an exchange, or route orders between exchanges according to their complicated criteria. Or when you do options pricing. Basically, everything in this field.

So something that produces nothing of value to civilization. Gotcha.

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#59
post #22
post #3

As a general rule, if you find yourself comparing floating point numbers, that's probably not what you want. I'm wondering what they are going to do with other operators, >=, <= etc

Floating point numbers are dangerous but in 2023 we should find a way to improve the side effects. Playing with Python3: >>> +0.0==-0.0 True The C in GCC below also returns 1: #include int main() { float a = +0.0; float b = -0.0; printf("%d\n", a == b); }

Erlang too, now and in the future will say that minuszero==zero, it's a different more specific operator that's changing.

You'll get the same in python with

>>> -0. is 0.

False

Re: In Erlang/OTP 27, +0.0 will no longer be exactly equal to -0.0

#60

Earlier quoted context omitted.

Algorithmic trading, of course. High-frequency trading in particular. But any trading, in fact, when you run simulations for thousands of instruments and search among millions of parameters. Or when you implement an exchange, or route orders between exchanges according to their complicated criteria. Or when you do options pricing. Basically, everything in this field.

So something that produces nothing of value to civilization. Gotcha.

Well, I assume you want to sell your hard-earned stocks of civilization-helping companies sometimes...
Post reply on HN