1 #define MAIN(x) math##x
5 #if A_PREREQ_GNUC(3, 0)
6 #pragma GCC diagnostic ignored "-Wfloat-conversion"
7 #endif /* -Wfloat-conversion */
8 #if A_PREREQ_GNUC(3, 0) || __has_warning("-Wfloat-equal")
9 #pragma GCC diagnostic ignored "-Wfloat-equal"
10 #endif /* -Wfloat-equal */
11 #if A_PREREQ_GNUC(4, 6) || __has_warning("-Wdouble-promotion")
12 #pragma GCC diagnostic ignored "-Wdouble-promotion"
13 #endif /* -Wdouble-promotion */
15 #if !defined __STDC_VERSION__ || (defined(_MSC_VER) && (_MSC_VER < 1800))
17 #define isinf(x) isinf_(x)
18 static A_INLINE a_bool
isinf_(a_float x
) { return x
+ x
== x
&& x
; }
21 #define isnan(x) isnan_(x)
22 static A_INLINE a_bool
isnan_(a_float x
) { return x
!= x
; }
24 #define sqrtf(x) sqrt(x)
25 #endif /* __STDC_VERSION__ */
27 static void test_u32_sqrt(void)
29 TEST_BUG(a_u32_sqrt(A_U32_C(~0)) == A_U16_C(0xFFFF));
30 TEST_BUG(a_u32_sqrt(A_U32_C(0x10000)) == A_U16_C(0x100));
31 TEST_BUG(a_u32_sqrt(A_U32_C(0xFFFFFFFF)) == A_U16_C(0xFFFF));
34 static void test_u64_sqrt(void)
36 TEST_BUG(a_u64_sqrt(A_U64_C(~0)) == A_U32_C(0xFFFFFFFF));
37 TEST_BUG(a_u64_sqrt(A_U64_C(0x10000)) == A_U32_C(0x100));
38 TEST_BUG(a_u64_sqrt(A_U64_C(0xFFFFFFFF)) == A_U32_C(0xFFFF));
39 TEST_BUG(a_u64_sqrt(A_U64_C(0x100000000)) == A_U32_C(0x10000));
40 TEST_BUG(a_u64_sqrt(A_U64_C(0xFFFFFFFFFFFFFFFF)) == A_U32_C(0xFFFFFFFF));
43 static void test_f32_rsqrt(void)
53 A_F32_C(2.5) * A_F32_C(2.5),
55 for (i
= 0; i
!= A_LEN(data
); ++i
)
57 debug("1/sqrt(%g):\t%-10g%-10g\n", data
[i
], 1 / a_f32_sqrt(data
[i
]), a_f32_rsqrt(data
[i
]));
61 static void test_f64_rsqrt(void)
71 A_F64_C(2.5) * A_F64_C(2.5),
73 for (i
= 0; i
!= A_LEN(data
); ++i
)
75 debug("1/sqrt(%g):\t%-10g%-10g\n", data
[i
], 1 / a_f64_sqrt(data
[i
]), a_f64_rsqrt(data
[i
]));
79 static void test_sum(int argc
, char *argv
[])
81 a_size i
, n
= a_cast_s(a_size
, argc
);
82 a_float
*p
= a_new(a_float
, A_NULL
, n
);
84 for (i
= 0; i
< n
; ++i
)
87 p
[i
] = strtonum(argv
[i
], &endptr
);
91 for (i
= 0; i
< n
; ++i
)
93 debug("%c%" A_FLOAT_PRI
"g", i
? ',' : 0, p
[i
]);
95 debug("}:%" A_FLOAT_PRI
"g,%" A_FLOAT_PRI
"g,%" A_FLOAT_PRI
"g\n",
96 a_float_sum(p
, n
), a_float_sum1(p
, n
), a_float_sum2(p
, n
));
101 static void test_mean(int argc
, char *argv
[])
103 a_size i
, n
= a_cast_s(a_size
, argc
);
104 a_float
*p
= a_new(a_float
, A_NULL
, n
);
106 for (i
= 0; i
< n
; ++i
)
109 p
[i
] = strtonum(argv
[i
], &endptr
);
113 for (i
= 0; i
< n
; ++i
)
115 debug("%c%" A_FLOAT_PRI
"g", i
? ',' : 0, p
[i
]);
117 debug("}:%" A_FLOAT_PRI
"g\n", a_float_mean(p
, n
));
122 static void test_push(int argc
, char *argv
[])
125 a_float array
[] = {0, 1, 2, 3, 4, 5, 6, 7};
126 for (i
= 0; i
< A_LEN(array
); ++i
)
128 debug("%+" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
130 a_float_push_fore(array
, A_LEN(array
), -1);
131 for (i
= 0; i
< A_LEN(array
); ++i
)
133 debug("%+" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
135 a_float_push_back(array
, A_LEN(array
), -1);
136 for (i
= 0; i
< A_LEN(array
); ++i
)
138 debug("%+" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
141 a_float cache
[] = {-1, -2};
142 a_float_push_fore_(array
, A_LEN(array
), cache
, A_LEN(cache
));
144 for (i
= 0; i
< A_LEN(array
); ++i
)
146 debug("%+" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
149 a_float cache
[] = {-2, -1};
150 a_float_push_back_(array
, A_LEN(array
), cache
, A_LEN(cache
));
152 for (i
= 0; i
< A_LEN(array
); ++i
)
154 debug("%+" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
157 a_float cache
[] = {-0, -1, -2, -3, -4, -5, -6, -7, -8, -9};
158 a_float_push_fore_(array
, A_LEN(array
), cache
, A_LEN(cache
));
160 for (i
= 0; i
< A_LEN(array
); ++i
)
162 debug("%+" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
165 a_float cache
[] = {-9, -8, -7, -6, -5, -4, -3, -2, -1, -0};
166 a_float_push_fore_(array
, A_LEN(array
), cache
, A_LEN(cache
));
168 for (i
= 0; i
< A_LEN(array
); ++i
)
170 debug("%+" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
176 static void test_roll(int argc
, char *argv
[])
179 a_float array
[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
181 for (i
= 0; i
< A_LEN(array
); ++i
)
183 debug("%" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
185 a_float_roll_fore(array
, A_LEN(array
));
186 for (i
= 0; i
< A_LEN(array
); ++i
)
188 debug("%" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
190 a_float_roll_back(array
, A_LEN(array
));
191 for (i
= 0; i
< A_LEN(array
); ++i
)
193 debug("%" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
195 a_float_roll_fore_(array
, A_LEN(array
), shift
, 2);
196 for (i
= 0; i
< A_LEN(array
); ++i
)
198 debug("%" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
200 a_float_roll_back_(array
, A_LEN(array
), shift
, 2);
201 for (i
= 0; i
< A_LEN(array
); ++i
)
203 debug("%" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
205 a_float_roll_fore_(array
, A_LEN(array
), shift
, 15);
206 for (i
= 0; i
< A_LEN(array
); ++i
)
208 debug("%" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
210 a_float_roll_back_(array
, A_LEN(array
), shift
, 15);
211 for (i
= 0; i
< A_LEN(array
); ++i
)
213 debug("%" A_FLOAT_PRI
"g%c", array
[i
], i
+ 1 < A_LEN(array
) ? ' ' : '\n');
221 int main(int argc
, char *argv
[]) /* NOLINT(misc-definitions-in-headers) */
228 a_f64 min
= A_F64_MIN
;
229 a_f64 max
= A_F64_MAX
;
230 a_f64 inf
= A_F64_INF
;
231 a_f64 nan
= A_F64_NAN
;
232 debug("64 min = %-12g max = %g\n", min
, max
);
233 debug("64 inf = %-12g nan = %g\n", inf
, nan
);
236 a_f32 min
= A_F32_MIN
;
237 a_f32 max
= A_F32_MAX
;
238 a_f32 inf
= A_F32_INF
;
239 a_f32 nan
= A_F32_NAN
;
240 debug("32 min = %-12g max = %g\n", min
, max
);
241 debug("32 inf = %-12g nan = %g\n", inf
, nan
);
244 a_float min
= A_FLOAT_MIN
;
245 a_float max
= A_FLOAT_MAX
;
246 a_float inf
= A_FLOAT_INF
;
247 a_float nan
= A_FLOAT_NAN
;
248 debug("min = %-12" A_FLOAT_PRI
"g max = %" A_FLOAT_PRI
"g\n", min
, max
);
249 debug("inf = %-12" A_FLOAT_PRI
"g nan = %" A_FLOAT_PRI
"g\n", inf
, nan
);
253 a_float x
= A_FLOAT_EPSILON
/ 2;
254 TEST_BUG(isinf(a_float_expm1(A_FLOAT_INF
)));
255 TEST_BUG(isnan(a_float_expm1(A_FLOAT_NAN
)));
256 debug("expm1(%.15" A_FLOAT_PRI
"g)=%.15" A_FLOAT_PRI
"g\n", x
, a_float_expm1(x
));
257 debug("exp(%.15" A_FLOAT_PRI
"g)-1=%.15" A_FLOAT_PRI
"g\n", x
, a_float_exp(x
) - 1);
261 a_float x
= A_FLOAT_EPSILON
/ 2;
262 TEST_BUG(isinf(a_float_log1p(A_FLOAT_INF
)));
263 TEST_BUG(isnan(a_float_log1p(A_FLOAT_NAN
)));
264 debug("log1p(%.15" A_FLOAT_PRI
"g)=%.15" A_FLOAT_PRI
"g\n", x
, a_float_log1p(x
));
265 debug("log(1+%.15" A_FLOAT_PRI
"g)=%.15" A_FLOAT_PRI
"g\n", x
, a_float_log(x
+ 1));
269 a_float x
= A_FLOAT_MAX
/ A_FLOAT_SQRT2
;
270 a_float y
= A_FLOAT_MAX
/ A_FLOAT_SQRT2
;
271 TEST_BUG(!isinf(a_float_hypot(x
, y
)));
272 TEST_BUG(isinf(a_float_hypot(A_FLOAT_INF
, A_FLOAT_NAN
)));
273 TEST_BUG(isinf(a_float_hypot(A_FLOAT_NAN
, A_FLOAT_INF
)));
274 TEST_BUG(isnan(a_float_hypot(A_FLOAT_NAN
, A_FLOAT_NAN
)));
277 a_float x
= A_FLOAT_MAX
/ A_FLOAT_SQRT3
;
278 a_float y
= A_FLOAT_MAX
/ A_FLOAT_SQRT3
;
279 a_float z
= A_FLOAT_MAX
/ A_FLOAT_SQRT3
;
280 TEST_BUG(!isinf(a_float_hypot3(x
, y
, z
)));
281 TEST_BUG(isinf(a_float_hypot3(A_FLOAT_INF
, A_FLOAT_NAN
, A_FLOAT_NAN
)));
282 TEST_BUG(isinf(a_float_hypot3(A_FLOAT_NAN
, A_FLOAT_INF
, A_FLOAT_NAN
)));
283 TEST_BUG(isinf(a_float_hypot3(A_FLOAT_NAN
, A_FLOAT_NAN
, A_FLOAT_INF
)));
284 TEST_BUG(isnan(a_float_hypot3(A_FLOAT_NAN
, A_FLOAT_NAN
, A_FLOAT_NAN
)));
288 test_sum(argc
- 1, argv
+ 1);
289 test_mean(argc
- 1, argv
+ 1);
290 test_push(argc
- 1, argv
+ 1);
291 test_roll(argc
- 1, argv
+ 1);
294 switch (a_hash_bkdr(argv
[1], 0))
296 case 0x001E5957: /* sum */
297 test_sum(argc
- 2, argv
+ 2);
299 case 0x0EB5AF9D: /* mean */
300 test_mean(argc
- 2, argv
+ 2);
302 case 0x0F20D22E: /* push */
303 test_push(argc
- 1, argv
+ 1);
305 case 0x0F63D79D: /* roll */
306 test_roll(argc
- 1, argv
+ 1);