kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

builtin_fp_cmp_negation.c (1803B)


      1 /* Route B — negating a floating comparison folds to the unordered dual.
      2  *
      3  * Because FP compares are delayed SV_CMPs, `!(a < b)` becomes the NaN-correct
      4  * unordered relation rather than a bare bitwise negate:
      5  *   !(a <  b) == UGE   (a >= b OR unordered)
      6  *   !(a <= b) == UGT
      7  *   !(a >  b) == ULE
      8  *   !(a >= b) == ULT
      9  *   !(a == b) == UNE   (already; C `!=` is unordered)
     10  *   !islessgreater(a, b) == UEQ
     11  * For ordinary operands these behave like the plain (negated) comparison; for
     12  * a NaN operand every negated ordered relation is true. */
     13 static double mknan(void) {
     14   double z = 0.0;
     15   return z / z;
     16 }
     17 
     18 int test_main(void) {
     19   double nan = mknan();
     20   double a = 1.0, b = 2.0;
     21   int rc = 0;
     22 
     23   /* !(a < b) -> UGE */
     24   if (!(a < b) != 0) rc |= 1 << 0;   /* 1<2 true  -> 0 */
     25   if (!(b < a) != 1) rc |= 1 << 1;   /* 2<1 false -> 1 */
     26   if (!(nan < a) != 1) rc |= 1 << 2; /* NaN unordered -> 1 */
     27 
     28   /* !(a <= b) -> UGT */
     29   if (!(a <= b) != 0) rc |= 1 << 3;
     30   if (!(b <= a) != 1) rc |= 1 << 4;
     31   if (!(nan <= a) != 1) rc |= 1 << 5;
     32 
     33   /* !(a > b) -> ULE */
     34   if (!(b > a) != 0) rc |= 1 << 6;
     35   if (!(a > b) != 1) rc |= 1 << 7;
     36   if (!(nan > a) != 1) rc |= 1 << 8;
     37 
     38   /* !(a >= b) -> ULT */
     39   if (!(b >= a) != 0) rc |= 1 << 9;
     40   if (!(a >= b) != 1) rc |= 1 << 10;
     41   if (!(nan >= a) != 1) rc |= 1 << 11;
     42 
     43   /* !(a == b) -> UNE */
     44   if (!(a == a) != 0) rc |= 1 << 12;
     45   if (!(a == b) != 1) rc |= 1 << 13;
     46   if (!(nan == a) != 1) rc |= 1 << 14; /* NaN never equal -> !false = 1 */
     47 
     48   /* !islessgreater -> UEQ (equal OR unordered) */
     49   if (!__builtin_islessgreater(a, a) != 1) rc |= 1 << 15;   /* equal -> 1 */
     50   if (!__builtin_islessgreater(a, b) != 0) rc |= 1 << 16;   /* distinct -> 0 */
     51   if (!__builtin_islessgreater(nan, a) != 1) rc |= 1 << 17; /* NaN -> 1 */
     52 
     53   return rc == 0 ? 42 : 0;
     54 }