Live data from Hacker News

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

erlangforums.com

91–100 of 236 posts

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

#91
post #11

Earlier quoted context omitted.

> if you find yourself comparing floating point numbers, that's probably not what you want Can you motivate this with an example for me? For instance, I think of games or location data encoded as FP; then, clearly, comparing them is a critical task to know questions like "what is closer" and so on. What am I missing?

Caveat: In the following, I use "comparison" to mean "check for equality". Floating point numbers lose precision because binary arithmetic doesn't represent decimal in all cases ( 1/3 is an easy example). It's not hard to get into a situation where you're asking if a number is 0.0 but due to a precision error the number you have is 0.00000000000001 or whatever and it should have been zero. If you're dealing with anyt…

> Floating point numbers lose precision because binary arithmetic doesn't represent decimal in all cases.

That’s not the reason. A counterexample is decimal arithmetic. That represents decimal in all cases, yet loses precision when doing calculations. Once you start doing division that applies even to arbitrarily sized decimal numbers.

The correct reason is because the subset of the reals that is representable as IEEE float isn’t closed under the operations people want to perform on them, including the basic ones of addition, multiplication and division.

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

#92
post #84

Earlier quoted context omitted.

In general, this is good advice. However, there are cases where comparing floating point numbers for equality works just fine. For example, if you have a variable 'v' and want to update it to a new value 'f', you can do 'if (v == f)' to check if the variable would change. Or if you have a sentinel value -1.0, it is perfectly ok to do 'if (a == -1.0)' In general, if you look for a number 'f' in variable 'v', you can s…

> For example, if you have a variable 'v' and want to update it to a new value 'f', you can do 'if (v == f)' to check if the variable would change. Isn't it strictly faster to simply assign? No branching, no branch predictions, only one instruction in all cases.

A typically pattern is:

  float freq = getParameter(FILTER_FREQUENCY);
  float coeff;
  if (freq != mFreq) {
    coeff = calculateCoeffFromFrequency(freq); // expensive
    mFreq = freq;
    mCoeff = coeff;
  } else {
    coeff = mCoeff; // use cached value
  }
  // use coeff

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

#93
post #68

Earlier quoted context omitted.

What’s the use case for different values?

It's a natural consequence of the IEEE 754 standard for floating point numbers.

To be clear, it was added to the standard because there was user demand for it.

Zero is already special cased in IEEE 754 (along with the rest of the denormals, because of the implied leading mantissa bit), the implementation would be no harder if you just only had a single zero. However, back when the standard was being created, when a single zero value was proposed there was pushback from people in the user community who depended on knowing which side of the zero they underflowed on their own floating point implementations.

Many people think that negative zero is just an engineering artefact. This is not true, it is a feature that was asked for, debated, and then added...

... almost certainly because it was an engineering artefact in a previous system that someone managed to depend on, https://xkcd.com/1172/ style.

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

#94
post #68

Earlier quoted context omitted.

What’s the use case for different values?

Float stuff like 1.f / (+0.f) = infinity and 1.f / (-0.f) = -infinity. And maybe complex number shenanigans and multi valued functions? Maybe someone familiar with mathematics can tell us more. :)

The best example on kahan's webpage is Borda's mouthpiece. Signed zero makes it look right, unsigned creates a singularity

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

#95

Earlier quoted context omitted.

I've always held that the numbers themselves are perfectly precise. It's the operations that don't do what you expect. Of course, that observation may be more or less useful, depending on circumstances.

Somewhere in the distant past a second grade me is staring at his math homework and fuming over the frustratingly ambiguous meaning of the minus sign. Is it an operator? A property? Both?

It's only ambiguous if you think it does two things. I say it does one thing.

-4 always removes 4, whether or not there is a number to the left.

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

#96
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.

The tolerance you need depends on how you calculated the number, so there's no way to have a sensible default.

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

#97
post #94

Earlier quoted context omitted.

Float stuff like 1.f / (+0.f) = infinity and 1.f / (-0.f) = -infinity. And maybe complex number shenanigans and multi valued functions? Maybe someone familiar with mathematics can tell us more. :)

The best example on kahan's webpage is Borda's mouthpiece. Signed zero makes it look right, unsigned creates a singularity

There are actually very clear and technical numerical analysis reasons for all of the weird stuff that happens in IEEE 754. The zero behavior, in particular, is because of this sort of thing.

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

#98

Earlier quoted context omitted.

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...

High frequency traders effectively charge money to provide liquidity.

But they provide far more than I need. I'm not worried about liquidity when I eventually sell those stocks, and if I could opt out of buying extra liquidity I definitely would.

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

#99

Earlier quoted context omitted.

Somewhere in the distant past a second grade me is staring at his math homework and fuming over the frustratingly ambiguous meaning of the minus sign. Is it an operator? A property? Both?

It's only ambiguous if you think it does two things. I say it does one thing. -4 always removes 4, whether or not there is a number to the left.

The problem arises with the way that this stuff is taught at a very elementary level, which then needs to be thrown away and relearned long after intuition and habits have formed around the old model. As an adult my reasoning is that it does indeed only do one thing: negation. it doesn't take anything away at all, if anything it actually adds information. Negating a four doesn't take it away, it just specifies a different (inverted) mapping of a given value with respect to zero. And this is still a very naive take, as someone with no background in number theory. But it's much more useful than say, Billy has four apples, he gives three to Mary, etc.

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

#100

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…

Honestly - I rather dislike this change. I'd much rather have 0 & -0 be precisely equal to each other and have some obscure library function like `isNegativeZero` for the extremely rare cases they'd need to be differentiated. 0 and -0 being distinct values is honestly just an accident of convenience with how floats are stored - there are two bit patterns that result in a value of 0 but because they're different patterns we've assigned an unwarranted amount of distinction to them.
Post reply on HN