nx_fx_f64_lit.nx source
↩ module page · 25 lines · 2314 B
1// nx_fx_f64_lit.nx -- LN36 + LN40 fixture: decimal exponent literals and long literals pack to the SAME bits
2// as a single correctly-rounded IEEE operation on exactly-representable operands (the hardware op is the
3// oracle: a quotient or product of exact operands is correctly rounded by IEEE-754). Exit 0 iff every check
4// holds, else a bitmask naming the failing checks (bit k = check k). license_tier: ORIGINAL
5func fx_id(x: f64) -> f64 { return x }
6func main() -> i64 {
7 var bad: i64 = 0
8 let ten9: f64 = fx_id(1000000000.0)
9 let e21: f64 = fx_id(1000000000000000000000.0) // 22 digits: the whole part alone overflows i64
10 let e20: f64 = fx_id(100000000000000000000.0) // 21 digits
11 if 1e9 != ten9 { bad = bad + 1 } // check 0: LN36 bare exponent
12 if 2.5e-3 != fx_id(2.5) / fx_id(1000.0) { bad = bad + 2 } // check 1: negative exponent
13 if 1e-9 != fx_id(1.0) / ten9 { bad = bad + 4 } // check 2
14 if 6.02e23 != fx_id(602.0) * e21 { bad = bad + 8 } // check 3: 10^21 exact, wide path
15 if 0.00000000000000000001 != fx_id(1.0) / e20 { bad = bad + 16 } // check 4: LN40 -- the 20-digit fraction that hung the compiler
16 if 1E+2 != fx_id(100.0) { bad = bad + 32 } // check 5: capital E, explicit plus
17 if 123.456e2 != fx_id(12345.6) { bad = bad + 64 } // check 6: exponent moves the point
18 if 9007199254740993.0 != fx_id(9007199254740992.0) { bad = bad + 128 } // check 7: 2^53+1 ties to even (2^53)
19 if 9007199254740995.0 != fx_id(9007199254740996.0) { bad = bad + 256 } // check 8: 2^53+3 ties to even (2^53+4)
20 if 0.1 + 0.2 == 0.3 { bad = bad + 512 } // check 9: correctly rounded short literals (must differ)
21 if 1e400 <= 1e308 { bad = bad + 1024 } // check 10: saturates to +inf, above the largest finite
22 if 12345678901234567890.5 != fx_id(12345678901234567890.0) + fx_id(0.5) { bad = bad + 2048 } // check 11: 20 whole digits + fraction
23 if 1e0 != fx_id(1.0) { bad = bad + 4096 } // check 12: zero exponent
24 return bad
25}