Live data from Hacker News

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

erlangforums.com

201–210 of 236 posts

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

#201

Earlier quoted context omitted.

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

Rigorously division by zero is "undefined" in mathematics.

You can totally define division by zero.

"There are mathematical structures in which [dividing by zero] is defined. [...] However, such structures do not satisfy every ordinary rule of arithmetic (the field axioms)." https://wikipedia.org/wiki/Division_by_zero

You're familiar with the ordinary rules of arithmetic (ORA!) applied to the real numbers. However, there are many number systems that follow different rules.

The rules of arithmetic for floats, wraparound ints, elliptic curves, and asymptotic analysis are all different from ORA! (and each other) but they are useful in their own ways.

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

#202
post #165
post #52

Earlier quoted context omitted.

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

what people want varies, but often what people doing numerical programming want is to write their monomorphic code in infix syntax so they can more easily see bugs in it they're already familiar with rounding errors from that perspective you're suggesting taking a step backwards from fortran i toward assembly language the erlang compiler bug presented is not an example of what you're talking about because you're talk…

Fortran would be an interesting case, because say C++ is polymorphic, and so are all dynamic programming languages with more than 1 type (x == y could be a string or float comparison)

But I would still say that floating point equality is a vanishingly rare operation

I can't think of any real use case for it, other than maybe some (bad, incomplete) unit tests that assert 1.0 == x and assert 1.0 == y

And that use case is perfectly served by float_equals(), and arguably served better if it has some options. Although probably abs(x - y) ---

Can you show some real use cases for floating point equality in good, production code? (honest question)

It's similar to hashing floats, which Go and Python do allow. I made an honest request for examples of float hashing:

https://lobste.rs/s/9e8qsh/go_1_21_may_have_clear_x_builtin#...

https://old.reddit.com/r/ProgrammingLanguages/comments/10bm2...

I didn't get any answers that appeared realistic. Some people said you might want to create a histogram of floats -- but that's obviously better served by bucketing floats, so you're hashing integers.

Another person said the same thing for quantizing to mesh.

One person suggested fraud detection for made-up values, but that was clearly addressed by converting the float to a bit pattern, and hashing the bit pattern.

----

This isn't a theoretical question since we're working on this for https://www.oilshell.org.

For that case it seems pretty clearly OK to omit === on floats, since I use awk and R for simple stats and percentages, and that's likely what people would do with a shell.

Though as always I'm open to concrete counterexamples.

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

#203
post #68

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…

What’s the use case for different values?

Floating point numbers don't represent all possible values, just a subset of values representable by a number of bits used. Therefore, in some cases it's reasonable to treat floating point numbers not as "exact point on a number scale", but rather a range between a number and the next possible representable number.

In the case of +0.0 and -0.0, they can be treated as values between zero and the smallest representable number (about 5.4E-079 for 32 bit floats). It isn't a very common use case since dealing with such small numbers isn't a very common thing, but it is definitely a possibility.

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

#204
post #190

Earlier quoted context omitted.

So no pensions, sovereign wealth funds, or scholarship funds? And by what mechanism is capital allocated?

https://en.wikipedia.org/wiki/Communism

Well, prepare the firing squads! What the world definitely needs is more fire squads, I presume.

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

#205
post #202
post #165

Earlier quoted context omitted.

what people want varies, but often what people doing numerical programming want is to write their monomorphic code in infix syntax so they can more easily see bugs in it they're already familiar with rounding errors from that perspective you're suggesting taking a step backwards from fortran i toward assembly language the erlang compiler bug presented is not an example of what you're talking about because you're talk…

Fortran would be an interesting case, because say C++ is polymorphic, and so are all dynamic programming languages with more than 1 type (x == y could be a string or float comparison) But I would still say that floating point equality is a vanishingly rare operation I can't think of any real use case for it, other than maybe some (bad, incomplete) unit tests that assert 1.0 == x and assert 1.0 == y And that use case…

i gave some examples in https://news.ycombinator.com/item?id=35883963, though arguably those are not very concrete. also i pointed out there why unit tests that use exact comparison on floats are not necessarily bad: ieee-784 specifies bit-exact results for the five fundamental arithmetic operations, and if your compiler is introducing rounding errors, you want your tests to fail. (or introducing nonerrors, in the case where it's introducing fmas.)

even hashing is useful for memoization

i think probably you're asking in the wrong places

the lapack source might be a better place to look; we can probably suppose that if something is in lapack it's realistic and also not a bug, and numerical code doesn't get more 'good, production' than lapack

in dgelsx for example i find

          ELSE IF( ANRM.EQ.ZERO ) THEN
    *
    *        Matrix all zero. Return zero solution.
    *
             CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
and also (fairly dubious, at least to my uneducated eye)

    *     Determine RANK using incremental condition estimation
    *
          WORK( ISMIN ) = ONE
          WORK( ISMAX ) = ONE
          SMAX = ABS( A( 1, 1 ) )
          SMIN = SMAX
          IF( ABS( A( 1, 1 ) ).EQ.ZERO ) THEN
             RANK = 0
             CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
             GO TO 100
          ELSE
             RANK = 1
          END IF
as well as some sentinel-value checks

and in dlar1v:

                WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )
                IF( WORK( INDLPL+I ).EQ.ZERO )
         $                      WORK( INDS+I ) = LLD( I )
and also

                TMP = D( I ) / DMINUS
                IF(DMINUS.LT.ZERO) NEG2 = NEG2 + 1
                WORK( INDUMN+I ) = L( I )*TMP
                WORK( INDP+I-1 ) = WORK( INDP+I )*TMP - LAMBDA
                IF( TMP.EQ.ZERO )
         $           WORK( INDP+I-1 ) = D( I ) - LAMBDA
and also

          IF( ABS(MINGMA).EQ.ZERO )
         $   MINGMA = EPS*WORK( INDS+R1-1 )
of course float comparisons for ordering are much more common than float comparisons for equality, but there are numerous realistic examples of float comparisons for equality in lapack and, i think, in applied mathematics in general

but if you ask an audience of type theorists, sysadmins, and web developers, they won't know that; they aren't numerical analysts and probably haven't inverted a submatrix since sophomore math class, if ever

(there are 6550 files in lapack 3.9.0 of which i looked through 15 to find these examples, suggesting that there are on the order of 1000 realistic examples in there; eventually i'd probably find one that wasn't even comparing to zero)

plausibly instead of giving them floating point by default you should give them fixed point with, say, nine digits after the decimal point; that was the approach knuth took in tex, for example, to guarantee reproducibility, but it also gives human-predictable rounding. and in most cases it should be perfectly adequate for simple stats and percentages. as a bonus you get 64 bits of precision instead of 53

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

#206
post #153

Earlier quoted context omitted.

not in ieee-754, only in reality

Numbers are abstract concepts in general. There is no fundamental reality only "real" numbers.

the question of whether mathematical objects like 53 are more or less real than the historically contingent universe is indeed very interesting

however, it is irrelevant to the fact that a commenter was disagreeing because they had confused ieee-754 division with the division operation on so-called 'real' numbers

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

#207
post #171

Earlier quoted context omitted.

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 communi…

i think the rationale in https://people.freebsd.org/~das/kahan86branch.pdf goes well above and beyond 'an engineering artefact in a previous system that someone managed to depend on'

unfortunately this scan is missing some pages

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

#208
post #100

Earlier quoted context omitted.

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…

> 0 and -0 being distinct values is honestly just an accident of convenience with how floats are stored That's not at all true. The inclusion of negative zero in ieee 754 was a deliberate design choice, and if it were considered desirable that zero should be unsigned, then the bit pattern assigned to -0 would not have been so assigned. See 'much ado about nothing's sign bit'[0], by one of the principal authors of iee…

unfortunately this scan of kahan's chapter is missing some pages

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

#209
post #194

Earlier quoted context omitted.

There is an example in the article about compiler optimization, and they state that other similar instances may exist.

The example for the compiler just seems like it wants a property that types don't necessarily even have (Equivalence), so my instinct would be that it's probably just broken and this is the tip of the iceberg or if the compiler does care about this property it should know floats don't have Equivalence and thus 0.0 == -0.0 isn't cause to perform this optimisation.

it's using the =:= operator you say it should be using, not the == operator you incorrectly say it is using

however, that operator was originally defined incorrectly, and now they are fixing that bug

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

#210
post #113
post #110

Earlier quoted context omitted.

there is no such thing as -0. if you want to say "zero approaching from negative one", fine, say that. but that IS NOT the same thing as -0. zero is just zero, it doesn't have a sign. some people just want everything to fit in a nice neat box, and sometimes folks, life is not like that. this is an awful change, injecting meaning where there is no room for it.

-0 exists. It's just not a mathematical object. It's an IEEE754 signed-magnitude bit-pattern — one that is distinct from the IEEE754 signed-magnitude bit-pattern we call +0. Both of these bit-patterns encode the semantic meaning of the mathematical object 0; but that doesn't mean that the bit patterns are the same "thing." Compare/contrast: the JSON document "0" vs the JSON document "0.0". Both encode the same type (…

groups and semilattices are mutually exclusive; semilattices can't have any inverse elements
Post reply on HN