Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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



Thanks for actually going and looking! I would say that this supports the idea of float_equals(x, 0.0) or even float_equals_zero(x) :)

It wouldn't be too surprising to me if 90% of float equalities in real code are comparisons to 0.0 or 1.0 or -1.0 (that's what I meant in my original post, there was a typo)

The point about x >= 0 and x <= 0 is interesting. I suppose to be consistent, you would also remove those operators on floats, although for something awk-like, I don't think it matters either way.

---

The other point is that it looks like the Fortran code isn't actually using == or x.eq.zero polymorphically!

So the first point is that I would want to understand conceptually where float equality would be equal. You mentioned fixed points, although there I also suspect that abs(x - y) < eps is a better test in most situations, though certainly there could be counterexamples.

The second point is -- would any of those situations be polymorphic with int and float, or string and float? It depends on the language, but it seems vanishingly unlikely in most languages, and in particular in say in C++

I would probably go look at the equivalent Eigen code if it mattered with respect to Oil, but it probably doesn't


yeah, i also wrote a cube root routine using newton's method yesterday and came to the conclusion that |x - x'| < threshold was a better approach in that case. maybe in every case, maybe not

i agree that prefix notation is not as bad for these as i had thought before looking

i think there are plausible cases where your float might be polymorphic with double, complex, a vector, a matrix, or an element of a galois field, but i think it would only be polymorphic with int in cases like stopping change propagation when an observable value gets recomputed to the same value from new inputs, and in those cases what you need is exact bitwise equality, not arithmetic equality

an awk-like thing might be better with fixed-point, like tex and metafont; you could call the data type 'btc` and represent it as a 64-bit integer that's multiplied by 10*-8 for output





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: