try to compile with -std=c90 1/n
[liba.git] / test / math.h
blobe7d8c2f78590ebc4046c5d5f53203f5cac8094aa
1 #define MAIN(x) math##x
2 #include "test.h"
3 #include "a/math.h"
5 #if A_PREREQ_GNUC(3, 0)
6 #pragma GCC diagnostic ignored "-Wfloat-conversion"
7 #endif /* -Wfloat-conversion */
8 #if A_PREREQ_GNUC(4, 6) || __has_warning("-Wdouble-promotion")
9 #pragma GCC diagnostic ignored "-Wdouble-promotion"
10 #endif /* -Wdouble-promotion */
12 static void test_u32_sqrt(void)
14 TEST_BUG(a_u32_sqrt(A_U32_C(~0)) == A_U16_C(0xFFFF));
15 TEST_BUG(a_u32_sqrt(A_U32_C(0x10000)) == A_U16_C(0x100));
16 TEST_BUG(a_u32_sqrt(A_U32_C(0xFFFFFFFF)) == A_U16_C(0xFFFF));
19 static void test_u64_sqrt(void)
21 TEST_BUG(a_u64_sqrt(A_U64_C(~0)) == A_U32_C(0xFFFFFFFF));
22 TEST_BUG(a_u64_sqrt(A_U64_C(0x10000)) == A_U32_C(0x100));
23 TEST_BUG(a_u64_sqrt(A_U64_C(0xFFFFFFFF)) == A_U32_C(0xFFFF));
24 TEST_BUG(a_u64_sqrt(A_U64_C(0x100000000)) == A_U32_C(0x10000));
25 TEST_BUG(a_u64_sqrt(A_U64_C(0xFFFFFFFFFFFFFFFF)) == A_U32_C(0xFFFFFFFF));
28 static void test_f32_rsqrt(void)
30 a_f32 data[] = {
31 A_F32_C(0.0),
32 A_F32_C(-0.0),
33 A_F32_C(-1.0),
34 A_F32_C(1e-10),
35 A_F32_C(1.0),
36 A_F32_C(4.0),
37 A_F32_C(2.5) * A_F32_C(2.5),
39 for (unsigned int i = 0; i != sizeof(data) / sizeof(a_f32); ++i)
41 debug("1/sqrt(%g):\t%-10g%-10g\n", data[i], 1 / a_f32_sqrt(data[i]), a_f32_rsqrt(data[i]));
45 static void test_f64_rsqrt(void)
47 a_f64 data[] = {
48 A_F64_C(0.0),
49 A_F64_C(-0.0),
50 A_F64_C(-1.0),
51 A_F64_C(1e-10),
52 A_F64_C(1.0),
53 A_F64_C(4.0),
54 A_F64_C(2.5) * A_F64_C(2.5),
56 for (unsigned int i = 0; i != sizeof(data) / sizeof(a_f64); ++i)
58 debug("1/sqrt(%g):\t%-10g%-10g\n", data[i], 1 / a_f64_sqrt(data[i]), a_f64_rsqrt(data[i]));
62 static void test_sum(int argc, char *argv[])
64 a_size const n = a_cast_s(a_size, argc);
65 a_float *p = a_new(a_float, A_NULL, n);
66 for (a_size i = 0; i < n; ++i)
68 char *endptr;
69 p[i] = strtonum(argv[i], &endptr);
72 debug("{");
73 for (a_size i = 0; i < n; ++i)
75 debug("%c" A_FLOAT_PRI("", "g"), i ? ',' : 0, p[i]);
77 debug("}:" A_FLOAT_PRI("", "g,") A_FLOAT_PRI("", "g,") A_FLOAT_PRI("", "g\n"),
78 a_float_sum(p, n), a_float_sum1(p, n), a_float_sum2(p, n));
80 a_die(p);
83 static void test_mean(int argc, char *argv[])
85 a_size const n = a_cast_s(a_size, argc);
86 a_float *p = a_new(a_float, A_NULL, n);
87 for (a_size i = 0; i < n; ++i)
89 char *endptr;
90 p[i] = strtonum(argv[i], &endptr);
93 debug("{");
94 for (a_size i = 0; i < n; ++i)
96 debug("%c" A_FLOAT_PRI("", "g"), i ? ',' : 0, p[i]);
98 debug("}:" A_FLOAT_PRI("", "g\n"), a_float_mean(p, n));
100 a_die(p);
103 static void test_push(int argc, char *argv[])
105 a_float array[] = {0, 1, 2, 3, 4, 5, 6, 7};
106 for (a_size i = 0; i < A_LEN(array); ++i)
108 debug(A_FLOAT_PRI("+", "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
110 a_float_push_fore(array, A_LEN(array), -1);
111 for (a_size i = 0; i < A_LEN(array); ++i)
113 debug(A_FLOAT_PRI("+", "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
115 a_float_push_back(array, A_LEN(array), -1);
116 for (a_size i = 0; i < A_LEN(array); ++i)
118 debug(A_FLOAT_PRI("+", "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
121 a_float cache[] = {-1, -2};
122 a_float_push_fore_(array, A_LEN(array), cache, A_LEN(cache));
124 for (a_size i = 0; i < A_LEN(array); ++i)
126 debug(A_FLOAT_PRI("+", "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
129 a_float cache[] = {-2, -1};
130 a_float_push_back_(array, A_LEN(array), cache, A_LEN(cache));
132 for (a_size i = 0; i < A_LEN(array); ++i)
134 debug(A_FLOAT_PRI("+", "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
137 a_float cache[] = {-0, -1, -2, -3, -4, -5, -6, -7, -8, -9};
138 a_float_push_fore_(array, A_LEN(array), cache, A_LEN(cache));
140 for (a_size i = 0; i < A_LEN(array); ++i)
142 debug(A_FLOAT_PRI("+", "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
145 a_float cache[] = {-9, -8, -7, -6, -5, -4, -3, -2, -1, -0};
146 a_float_push_fore_(array, A_LEN(array), cache, A_LEN(cache));
148 for (a_size i = 0; i < A_LEN(array); ++i)
150 debug(A_FLOAT_PRI("+", "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
152 (void)argc;
153 (void)argv;
156 static void test_roll(int argc, char *argv[])
158 a_float array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
159 a_float shift[16];
160 for (a_size i = 0; i < A_LEN(array); ++i)
162 debug(A_FLOAT_PRI(, "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
164 a_float_roll_fore(array, A_LEN(array));
165 for (a_size i = 0; i < A_LEN(array); ++i)
167 debug(A_FLOAT_PRI(, "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
169 a_float_roll_back(array, A_LEN(array));
170 for (a_size i = 0; i < A_LEN(array); ++i)
172 debug(A_FLOAT_PRI(, "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
174 a_float_roll_fore_(array, A_LEN(array), shift, 2);
175 for (a_size i = 0; i < A_LEN(array); ++i)
177 debug(A_FLOAT_PRI(, "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
179 a_float_roll_back_(array, A_LEN(array), shift, 2);
180 for (a_size i = 0; i < A_LEN(array); ++i)
182 debug(A_FLOAT_PRI(, "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
184 a_float_roll_fore_(array, A_LEN(array), shift, 15);
185 for (a_size i = 0; i < A_LEN(array); ++i)
187 debug(A_FLOAT_PRI(, "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
189 a_float_roll_back_(array, A_LEN(array), shift, 15);
190 for (a_size i = 0; i < A_LEN(array); ++i)
192 debug(A_FLOAT_PRI(, "g") "%c", array[i], i + 1 < A_LEN(array) ? ' ' : '\n');
194 (void)argc;
195 (void)argv;
198 #include "a/hash.h"
200 int main(int argc, char *argv[]) /* NOLINT(misc-definitions-in-headers) */
202 test_u32_sqrt();
203 test_u64_sqrt();
204 test_f32_rsqrt();
205 test_f64_rsqrt();
207 a_f64 min = A_F64_MIN;
208 a_f64 max = A_F64_MAX;
209 a_f64 inf = A_F64_INF;
210 a_f64 nan = A_F64_NAN;
211 debug("64 min = %-12g max = %g\n", min, max);
212 debug("64 inf = %-12g nan = %g\n", inf, nan);
215 a_f32 min = A_F32_MIN;
216 a_f32 max = A_F32_MAX;
217 a_f32 inf = A_F32_INF;
218 a_f32 nan = A_F32_NAN;
219 debug("32 min = %-12g max = %g\n", min, max);
220 debug("32 inf = %-12g nan = %g\n", inf, nan);
223 a_float min = A_FLOAT_MIN;
224 a_float max = A_FLOAT_MAX;
225 a_float inf = A_FLOAT_INF;
226 a_float nan = A_FLOAT_NAN;
227 debug("min = " A_FLOAT_PRI("-12", "g ") "max = " A_FLOAT_PRI("", "g\n"), min, max);
228 debug("inf = " A_FLOAT_PRI("-12", "g ") "nan = " A_FLOAT_PRI("", "g\n"), inf, nan);
231 #undef a_float_expm1
232 a_float x = A_FLOAT_EPSILON / 2;
233 TEST_BUG(isinf(a_float_expm1(A_FLOAT_INF)));
234 TEST_BUG(isnan(a_float_expm1(A_FLOAT_NAN)));
235 debug("expm1(" A_FLOAT_PRI(".15", "g") ")=" A_FLOAT_PRI(".15", "g\n"), x, a_float_expm1(x));
236 debug("exp(" A_FLOAT_PRI(".15", "g") ")-1=" A_FLOAT_PRI(".15", "g\n"), x, a_float_exp(x) - 1);
239 #undef a_float_log1p
240 a_float x = A_FLOAT_EPSILON / 2;
241 TEST_BUG(isinf(a_float_log1p(A_FLOAT_INF)));
242 TEST_BUG(isnan(a_float_log1p(A_FLOAT_NAN)));
243 debug("log1p(" A_FLOAT_PRI(".15", "g") ")=" A_FLOAT_PRI(".15", "g\n"), x, a_float_log1p(x));
244 debug("log(1+" A_FLOAT_PRI(".15", "g") ")=" A_FLOAT_PRI(".15", "g\n"), x, a_float_log(x + 1));
247 #undef a_float_hypot
248 a_float x = A_FLOAT_MAX / A_FLOAT_SQRT2;
249 a_float y = A_FLOAT_MAX / A_FLOAT_SQRT2;
250 TEST_BUG(!isinf(a_float_hypot(x, y)));
251 TEST_BUG(isinf(a_float_hypot(A_FLOAT_INF, A_FLOAT_NAN)));
252 TEST_BUG(isinf(a_float_hypot(A_FLOAT_NAN, A_FLOAT_INF)));
253 TEST_BUG(isnan(a_float_hypot(A_FLOAT_NAN, A_FLOAT_NAN)));
256 a_float x = A_FLOAT_MAX / A_FLOAT_SQRT3;
257 a_float y = A_FLOAT_MAX / A_FLOAT_SQRT3;
258 a_float z = A_FLOAT_MAX / A_FLOAT_SQRT3;
259 TEST_BUG(!isinf(a_float_hypot3(x, y, z)));
260 TEST_BUG(isinf(a_float_hypot3(A_FLOAT_INF, A_FLOAT_NAN, A_FLOAT_NAN)));
261 TEST_BUG(isinf(a_float_hypot3(A_FLOAT_NAN, A_FLOAT_INF, A_FLOAT_NAN)));
262 TEST_BUG(isinf(a_float_hypot3(A_FLOAT_NAN, A_FLOAT_NAN, A_FLOAT_INF)));
263 TEST_BUG(isnan(a_float_hypot3(A_FLOAT_NAN, A_FLOAT_NAN, A_FLOAT_NAN)));
265 if (argc < 2)
267 test_sum(argc - 1, argv + 1);
268 test_mean(argc - 1, argv + 1);
269 test_push(argc - 1, argv + 1);
270 test_roll(argc - 1, argv + 1);
271 return 0;
273 switch (a_hash_bkdr(argv[1], 0))
275 case 0x001E5957: /* sum */
276 test_sum(argc - 2, argv + 2);
277 break;
278 case 0x0EB5AF9D: /* mean */
279 test_mean(argc - 2, argv + 2);
280 break;
281 case 0x0F20D22E: /* push */
282 test_push(argc - 1, argv + 1);
283 break;
284 case 0x0F63D79D: /* roll */
285 test_roll(argc - 1, argv + 1);
286 break;
287 default:
288 debug("sum\n");
289 debug("mean\n");
290 debug("push\n");
291 debug("roll\n");
293 return 0;