1 | /********************************************************************** |
2 | * |
3 | * Float to string Test |
4 | * |
5 | **********************************************************************/ |
6 | import strconv |
7 | import math |
8 | |
9 | union Ufloat32 { |
10 | mut: |
11 | f f32 = f32(0) |
12 | b u32 |
13 | } |
14 | |
15 | union Ufloat64 { |
16 | mut: |
17 | f f64 = f64(0) |
18 | b u64 |
19 | } |
20 | |
21 | fn f64_from_bits1(b u64) f64 { |
22 | mut x := Ufloat64{} |
23 | x.b = b |
24 | // C.printf("bin: %016llx\n",x.f) |
25 | return unsafe { x.f } |
26 | } |
27 | |
28 | fn f32_from_bits1(b u32) f32 { |
29 | mut x := Ufloat32{} |
30 | x.b = b |
31 | // C.printf("bin: %08x\n",x.f) |
32 | return unsafe { x.f } |
33 | } |
34 | |
35 | fn test_float_to_str() { |
36 | test_cases_f32 := [ |
37 | f32_from_bits1(0x0000_0000), // +0 |
38 | f32_from_bits1(0x8000_0000), // -0 |
39 | f32_from_bits1(0xFFC0_0001), // sNan |
40 | f32_from_bits1(0xFF80_0001), // qNan |
41 | f32_from_bits1(0x7F80_0000), // +inf |
42 | f32_from_bits1(0xFF80_0000), // -inf |
43 | 1, |
44 | -1, |
45 | 10, |
46 | -10, |
47 | 0.3, |
48 | -0.3, |
49 | 1000000, |
50 | 123456.7, |
51 | 123e35, |
52 | -123.45, |
53 | 1e23, |
54 | f32_from_bits1(0x0080_0000), // smallest float32 |
55 | math.max_f32, |
56 | 383260575764816448.0, |
57 | ] |
58 | |
59 | exp_result_f32 := [ |
60 | '0e+00', |
61 | '-0e+00', |
62 | 'nan', |
63 | 'nan', |
64 | '+inf', |
65 | '-inf', |
66 | '1.e+00', |
67 | '-1.e+00', |
68 | '1.e+01', |
69 | '-1.e+01', |
70 | '3.e-01', |
71 | '-3.e-01', |
72 | '1.e+06', |
73 | '1.234567e+05', |
74 | '1.23e+37', |
75 | '-1.2345e+02', |
76 | '1.e+23', |
77 | '1.1754944e-38', // aprox from 1.1754943508 × 10−38, |
78 | '3.4028235e+38', |
79 | '3.8326058e+17', |
80 | ] |
81 | |
82 | test_cases_f64 := [ |
83 | f64_from_bits1(0x0000_0000_0000_0000), // +0 |
84 | f64_from_bits1(0x8000_0000_0000_0000), // -0 |
85 | f64_from_bits1(0x7FF0_0000_0000_0001), // sNan |
86 | f64_from_bits1(0x7FF8_0000_0000_0001), // qNan |
87 | f64_from_bits1(0x7FF0_0000_0000_0000), // +inf |
88 | f64_from_bits1(0xFFF0_0000_0000_0000), // -inf |
89 | 1, |
90 | -1, |
91 | 10, |
92 | -10, |
93 | 0.3, |
94 | -0.3, |
95 | 1000000, |
96 | 123456.7, |
97 | 123e45, |
98 | -123.45, |
99 | 1e23, |
100 | f64_from_bits1(0x0010_0000_0000_0000), // smallest float64 |
101 | math.max_f32, |
102 | 383260575764816448, |
103 | 383260575764816448, |
104 | // C failing cases |
105 | 123e300, |
106 | 123e-300, |
107 | 5.e-324, |
108 | -5.e-324, |
109 | ] |
110 | |
111 | exp_result_f64 := [ |
112 | '0e+00', |
113 | '-0e+00', |
114 | 'nan', |
115 | 'nan', |
116 | '+inf', |
117 | '-inf', |
118 | '1.e+00', |
119 | '-1.e+00', |
120 | '1.e+01', |
121 | '-1.e+01', |
122 | '3.e-01', |
123 | '-3.e-01', |
124 | '1.e+06', |
125 | '1.234567e+05', |
126 | '1.23e+47', |
127 | '-1.2345e+02', |
128 | '1.e+23', |
129 | '2.2250738585072014e-308', |
130 | '3.4028234663852886e+38', |
131 | '3.8326057576481645e+17', |
132 | '3.8326057576481645e+17', |
133 | '1.23e+302', // this test is failed from C sprintf!! |
134 | '1.23e-298', |
135 | '5.e-324', |
136 | '-5.e-324', |
137 | ] |
138 | |
139 | // test f32 |
140 | for c, x in test_cases_f32 { |
141 | // println(x) |
142 | s := strconv.f32_to_str(x, 8) |
143 | s1 := exp_result_f32[c] |
144 | // println("$s1 $s") |
145 | assert s == s1 |
146 | } |
147 | |
148 | // test f64 |
149 | for c, x in test_cases_f64 { |
150 | s := strconv.f64_to_str(x, 17) |
151 | s1 := exp_result_f64[c] |
152 | // println("$s1 $s") |
153 | assert s == s1 |
154 | } |
155 | |
156 | // test long format |
157 | assert strconv.f64_to_str_l('1e1'.f64()).len == 4 // '10.0' |
158 | assert strconv.f64_to_str_l('1e-1'.f64()).len == 3 // '0.1' |
159 | |
160 | for exp := 2; exp < 120; exp++ { |
161 | a := strconv.f64_to_str_l(('1e' + exp.str()).f64()) |
162 | // println(a) |
163 | assert a.len == exp + 3 |
164 | |
165 | b := strconv.f64_to_str_l(('1e-' + exp.str()).f64()) |
166 | // println(b) |
167 | assert b.len == exp + 2 |
168 | } |
169 | |
170 | // test rounding str conversion |
171 | // println( ftoa.f64_to_str(0.3456789123456, 4) ) |
172 | // assert ftoa.f64_to_str(0.3456789123456, 4)=="3.4568e-01" |
173 | // assert ftoa.f32_to_str(0.345678, 3)=="3.457e-01" |
174 | } |