In https://dlang.org/d-floating-point.html it is claimed: "[...] in order to preserve identities such as: if x>0, then 1/(1/x) > 0." But this is wrong, the identity doesn't hold anyway! Compile the following with DMD v2.074.0. void main() { import std.math : nextafter; double x = nextafter(0.0, 1.0); // produce smallest denormal number > 0. assert(x > 0); double y = 1/x; assert(y > 0); assert(1/y > 0); // fails assert(1/(1/x) > 0); // passes due to wrong optimuzation }
Right, it's a bit sloppy, I'm treating +0.0 as "> 0". The wording should actually be something like: identities such as: x and 1/(1/x) always have the same sign bit. (The point is that you can take the reciprocal without destroying the sign bit). > assert(1/y > 0); // fails That's because y is +infinity, so the result is +0.0. > assert(1/(1/x) > 0); // passes due to wrong optimuzation That's not a problem, the compiler was able to avoid creating a spurious NaN. It's allowed to use arbitrary intermediate precision.
@RazvanN7 created dlang/dlang.org pull request #3342 "Fix Issue 17324 - Floating point 1/(1/x) > 0 if x > 0 not generally true" fixing this issue: - Fix Issue 17324 - Floating point 1/(1/x) > 0 if x > 0 not generally true https://github.com/dlang/dlang.org/pull/3342
dlang/dlang.org pull request #3342 "Fix Issue 17324 - Floating point 1/(1/x) > 0 if x > 0 not generally true" was merged into master: - dc1295bbe6111c0e21155252695d59923f93cceb by Razvan Nitu: Fix Issue 17324 - Floating point 1/(1/x) > 0 if x > 0 not generally true https://github.com/dlang/dlang.org/pull/3342