fp32_parts_test.nx source
↩ module page · 83 lines · 2434 B
1// fp32_parts_test.nx -- round-trip literal conversion.
2//
3// Verifies fp32_from_parts produces the correct IEEE 754 bit pattern
4// for common literal values. These are the reference encodings the
5// parser will embed in VK_CONST_INT values when it hits TK_FLOAT.
6//
7// Canonical patterns cross-referenced against C compilers:
8// 0.0 -> 0x00000000
9// 1.0 -> 0x3F800000
10// 2.0 -> 0x40000000
11// 0.5 -> 0x3F000000
12// 1.5 -> 0x3FC00000
13// 3.14 -> 0x4048F5C3 (exact fp32; our integer encoder may round
14// by a ULP, so we allow ULP tolerance)
15
16import "syscalls.nx"
17import "quant.nx"
18
19func ulp_close(a: i64, b: i64) -> i64 {
20 // Exact match OR differ by at most 1 in the mantissa.
21 if a == b { return 1 }
22 let d: i64 = a - b
23 if d == 1 { return 1 }
24 if d == -1 { return 1 }
25 return 0
26}
27
28func main() -> i64 {
29 // 0.0
30 if fp32_from_parts(0, 0, 0) != 0 {
31 return __syscall(93, 10, 0, 0, 0, 0, 0)
32 }
33 if fp32_from_parts(0, 0, 1) != 0 {
34 return __syscall(93, 11, 0, 0, 0, 0, 0)
35 }
36
37 // 1.0 -> 0x3F800000
38 if fp32_from_parts(1, 0, 0) != 0x3F800000 {
39 return __syscall(93, 20, 0, 0, 0, 0, 0)
40 }
41 if fp32_from_parts(1, 0, 1) != 0x3F800000 {
42 return __syscall(93, 21, 0, 0, 0, 0, 0)
43 }
44
45 // 2.0 -> 0x40000000
46 if fp32_from_parts(2, 0, 0) != 0x40000000 {
47 return __syscall(93, 30, 0, 0, 0, 0, 0)
48 }
49
50 // 0.5 -> 0x3F000000
51 if fp32_from_parts(0, 5, 1) != 0x3F000000 {
52 return __syscall(93, 40, 0, 0, 0, 0, 0)
53 }
54
55 // 1.5 -> 0x3FC00000
56 if fp32_from_parts(1, 5, 1) != 0x3FC00000 {
57 return __syscall(93, 50, 0, 0, 0, 0, 0)
58 }
59
60 // 3.14 -> ~0x4048F5C3 (within 1 ULP)
61 let pi_bits: i64 = fp32_from_parts(3, 14, 2)
62 if ulp_close(pi_bits, 0x4048F5C3) != 1 {
63 return __syscall(93, 60, 0, 0, 0, 0, 0)
64 }
65
66 // 0.1 -> ~0x3DCCCCCD (recurring decimal, expect ULP tolerance)
67 let tenth_bits: i64 = fp32_from_parts(0, 1, 1)
68 if ulp_close(tenth_bits, 0x3DCCCCCD) != 1 {
69 return __syscall(93, 70, 0, 0, 0, 0, 0)
70 }
71
72 // 4.0 -> 0x40800000
73 if fp32_from_parts(4, 0, 0) != 0x40800000 {
74 return __syscall(93, 80, 0, 0, 0, 0, 0)
75 }
76
77 // 8.0 -> 0x41000000
78 if fp32_from_parts(8, 0, 0) != 0x41000000 {
79 return __syscall(93, 81, 0, 0, 0, 0, 0)
80 }
81
82 return 0
83}