153_fp_cmp_negation_b.toy (1478B)
1 // Route B: negating a delayed FP compare reaches the unordered dual. 2 // !(a < b) == UGE !(a <= b) == UGT 3 // !(a > b) == ULE !(a >= b) == ULT 4 // On NaN the ordered relation is false, so its negation (the unordered dual) is 5 // true. Each test fn returns 0 on success; __user_main sums them so a nonzero 6 // exit pinpoints the first failing predicate. NaN is built from runtime 0.0/0.0. 7 fn nan_via(x: f64): f64 { let z: f64 = x - x; return z / z; } 8 9 fn test_not_lt(): i64 { 10 if !(1.0 < 2.0) { return 1; } // !(true) -> false 11 if !(2.0 < 1.0) { } else { return 2; } // !(false) -> true 12 let n: f64 = nan_via(3.0); 13 if !(n < 1.0) { } else { return 3; } // UGE: NaN -> true 14 return 0; 15 } 16 17 fn test_not_le(): i64 { 18 if !(1.0 <= 1.0) { return 1; } 19 if !(2.0 <= 1.0) { } else { return 2; } 20 let n: f64 = nan_via(3.0); 21 if !(n <= 1.0) { } else { return 3; } // UGT: NaN -> true 22 return 0; 23 } 24 25 fn test_not_gt(): i64 { 26 if !(2.0 > 1.0) { return 1; } 27 if !(1.0 > 2.0) { } else { return 2; } 28 let n: f64 = nan_via(3.0); 29 if !(n > 1.0) { } else { return 3; } // ULE: NaN -> true 30 return 0; 31 } 32 33 fn test_not_ge(): i64 { 34 if !(2.0 >= 1.0) { return 1; } 35 if !(1.0 >= 2.0) { } else { return 2; } 36 let n: f64 = nan_via(3.0); 37 if !(n >= 1.0) { } else { return 3; } // ULT: NaN -> true 38 return 0; 39 } 40 41 fn __user_main(): i64 { 42 return test_not_lt() + test_not_le() + test_not_gt() + test_not_ge(); 43 } 44 45 fn main(): i32 { return __user_main() as i32; }