New blog post! I really hope I'll get a decent amount of people mad with this one 😈😈😈

It's OK to compare floating-points for equality:

https://lisyarus.github.io/blog/posts/its-ok-to-compare-floating-points-for-equality.html

#programming #computing #floatingpoint #geometry

It's OK to compare floating-points for equality

lisyarus blog

@lisyarus
> In reality it is a pretty deterministic (modulo compiler options, CPU flags, etc)

and then det(v, v) suddenly doesn't return 0.0 anymore because the compiler now targets a newer CPU with FMA and uses regular multiplication for `a.y * b.x` and FMA for `a.x * b.y - prev_result`, and FMA uses infinite precision so `a.x * b.y` can be slightly different from the result of the regular multiplication -_-

It annoys me that IEEE754 allows this and compilers (ab)use it

@Doomed_Daniel @lisyarus This is not an IEEE754 problem; IEEE754 defines FMA and unfused mul/add. It's up to each language to figure out how to compile compound expressions and what is permissible; C/C++ allow contraction by default, so you do get different results based on the platform or the underlying model - but you can also turn contraction off to fix this, or use languages that don't allow this implicit conversion.

@zeux @lisyarus IEEE754 explicitly allows contractions

IMHO compilers should put them behind -ffast-math or similar, not enabled by default

@Doomed_Daniel @lisyarus I agree that contraction should not be enabled unconditionally; Rust is an example of a language that doesn't do that - it follows IEEE 754 strictly. IEEE 754 does not explicitly allow contractions. In fact it has language that prohibits these by default, which C doesn't follow (clang will synthesize fma unconditionally without optimizations when supported)

@zeux @lisyarus
IEEE 754 at least seems to allow this as long as it can be switched off, doesn't require it to be disabled by default - or at least that's what the C/C++ standards and/or compilerwriters think

(GCC is extra fun because it only allows using -ffp-contract but ignores the FP_CONTRACT pragma)

@Doomed_Daniel @zeux @lisyarus again, that's not IEEE 754.

But it's not like the FP standard gets a vote on this. The language standards do whatever they want.

See also Kahan's rants on Java's choices wrt FP implementation in the 90s and early 2000s. Mind, in a lot of that he's railing against the idea of trying to aim for exact reproducibility since it was at the time impractical. By now it wouldn't be, though.

@rygorous @zeux @lisyarus
IIRC in a discussion about this years ago (and/or GCC bugtracker?) compiler-adjacent people argued that it does not violate IEEE 754, because the standard allows it as long as it can be controlled with a flag, or sth like that.

The language standard can do whatever it wants, but not claim that it conforms to IEEE 754 then?

@Doomed_Daniel @zeux @lisyarus Again, I don't understand what power you think the standard has here, though.

They can write all kinds of things into IEEE-754 that are then summarily ignored.

This is pretty much exactly how IEEE 754s traps have been handled by most langs for the past 40 years.

@rygorous @zeux @lisyarus
my assumption was that if a language/compiler says it implements IEEE 754 that it then by default conforms to that standard - but apparently that was optimistic/naive.

either way, this is a massive footgun that has become more relevant recently with x86-64-v3 becoming a popular target