Live data from Hacker News

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

erlangforums.com

151–160 of 236 posts

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

#151
post #83

Earlier quoted context omitted.

I was with you until the end First point: FPs are unique. Clearly true Second point: Combing FPs isn't lossless, across most/all arithmetic. Clearly true, the root of our discussion Third point: decimal arithmetic is lossy too. Strongly disagree. The system of representation is what is lossy - floating point. Arithmetic (between two decimal numbers) is clearly not lossy in and of itself, only as implemented with comp…

Decimal is only lossless if you track an indefinitely-growing suffix to your number with a big bar over it to indicate "repeating". It's basically working with rational numbers but more painful. Decimal numbers with any limit on digits, even a hundred, are lossy. Decimal numbers as used by humans outside of computers have limits on digits, so they are lossy.

Likewise, bit-limited integers are lossy as they are incomplete representations of ℤ, and are not reciprocal with division. The point being that, just like floating-point representations of ℝ, division will always be lossy in the general case unless you choose a symbolic algebra instead of numeric.

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

#152

Earlier quoted context omitted.

I don't think it's just that. 1/0 is infinity but 1/(-0) is -infinity

1/0 is undefined and 1/-0 is also undefined. what we have is lim(x->0+) 1/x = +inf and lim(x->0-) 1/x = -inf

this is wrong. ieee defines them

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

#153

Earlier quoted context omitted.

I don't think it's just that. 1/0 is infinity but 1/(-0) is -infinity

1/0 is undefined and 1/-0 is also undefined. what we have is lim(x->0+) 1/x = +inf and lim(x->0-) 1/x = -inf

not in ieee-754, only in reality

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

#154

Earlier quoted context omitted.

Shouldn't both of those be NaN? Does Erlang have a NaN?

The reason division by zero can be a number is that floating-point numbers aren't individual numbers but ranges of numbers. So 0.0 isn't really the integer 0, it is the range of numbers between 0 and the smallest representable non-zero number. So division by 0.0 may be division by zero, or it may be division by a very small number, in which case it would approach infinity. The same goes for the floating-point infinit…

this isn't true. floats don't have semantics of internals. they have semantics of exact points that do math with rounding (otherwise the result of subtracting 2 floats would sometimes be more than 1 float)

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

#155
post #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 patte…

the thread explains in the very first message that the existing semantics caused a subtle compiler bug in a way that makes it clear that you are not just wrong about the semantics of ieee-754 floating point but also about the pragmatics of how this affects real programs

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

#156
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

this is not about arithmetic comparison, it's about erlang's exact-equality operator

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

#157
post #108

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.

> I've always held that the numbers themselves are perfectly precise. It's the operations that don't do what you expect. I think that this is an oversimplification, and misses a key point. Floating point numbers can be interpreted in (at least) two distinct ways. In one use model, floating point numbers allow a sparse representation of selected points on the (extended) real number line. In this model, the numbers the…

the problem is the second interpretation is wrong. for example, exp(x) would give a higher value than it does since the average value of the exponent of a range is higher than the exponent of it's center.

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

#158
post #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 patte…

They're still ==.

=:= (=== in elixir) Somewhat means "and has the same binary form"

Fwiw, julia made the exact same choices.

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

#159

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…

So, in Erlang it will be the case that: +0.0 == -0.0 is true, I guess because they are very close +0.0 =:= -0.0 is false, I guess because they have different bits A =:= B for two different numbers of course, because they have different bits How does == work for other very close floating point values in Erlang? Is there some inconsistency here?

The only other distinction between == and =:= is for integers and floats. Integers are not =:= to the corresponding float, but are ==, so it has nothing to do with closeness.

-0.0 is a weird dumb non mathematical value that IEEE 754 put in (for example the standardized value for sqrt(-0.0) is not even justifiable based on their choices). I think they didn't want 1/(1/-Inf) to be Inf, or something.

In the end think of erlang's "==" as "equal in value" and "=:=" as "equal in representation in memory".

Now if you really want to raise the hackles of someone using Erlang, should ask why integers and floats don't have a well ordering, and what you should do when you sort them.

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

#160
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

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…

cesaref's comment is not good advice, it's not advice at all, it's a snarky take on how floating point is trickier than it looks

almost invariably floating-point calculations end up in some kind of comparison; if they didn't we'd probably do the calculations in a galois field or something instead

even equality comparison of floats is useful; there are an abundance of seminumerical algorithms which use it correctly on the results of computations. a trivial example is computing an attractive fixpoint by iterating a function and comparing each hare result to the previous iteration and to a tortoise. you have to be especially careful about x87 extended precision here

ieee-754 requires bit-exact results for the five fundamental operations

here is an example where your 'safe' generalization is not safe:

    #include 

    int main()
    {
      float f = 0.7;
      printf(f == 0.7 ? "ok\n" : "wtf\n");
      return 0;
    }
this prints 'wtf' on, for example, x86_64-linux-gnu
Post reply on HN