Search code examples
mathfloating-pointnumerical

Are x<=y and x-y<=0 equivalent in floating point arithmetic?


Assume that x,y are two floating point numbers. Then is that true:

x<=y <==> x-y<=0

in floating point arithmetic?

Thank for your ideas.

[Edit] Let us assume, additionally, that neither x nor y are NaN.

Is that possible that x<=y holds but not x-y<=0 or x-y<=0 holds but not x<=y.


Solution

  • [Note: I'm ignoring infinities and NaNs in this answer, as either trivially leads to non-equivalence.]

    If you've disabled subnormal numbers (or flush-to-zero behaviour), then it's possible to produce an underflow with the subtraction, resulting in non-equivalence between your two expressions.

    For example:

    #include <stdio.h>
    #define CSR_FLUSH_TO_ZERO (1 << 15)
    
    // Note: GCC-specific
    void disable_ftz(void) {
        unsigned csr = __builtin_ia32_stmxcsr();
        csr |= CSR_FLUSH_TO_ZERO;
        __builtin_ia32_ldmxcsr(csr);
    }
    
    int main(void) {
        disable_ftz();
    
        float x = 2.8e-45;
        float y = 1.4e-45;
    
        printf("%e\n", x);           // 2.802597e-45
        printf("%e\n", y);           // 1.401298e-45
    
        printf("%d\n", x <= y);      // 0
        printf("%d\n", (x-y) <= 0);  // 1
        return 0;
    }
    

    Note that this requires some compiler-specific magic on an x86. However, it's permissible to have a floating-point implementation that doesn't have subnormals at all, and on such systems no magic would be required to achieve the same non-equivalence.