initial commit
[libm] / test / io / t.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <math.h>
4 #include <fenv.h>
5 #include <string.h>
6
7 struct func {
8         char *name;
9         int args;
10         double (*f)();
11 } funcs[] = {
12         {"acos",  1, acos},
13         {"asin",  1, asin},
14         {"atan",  1, atan},
15         {"atan2", 2, atan2},
16         {"ceil",  1, ceil},
17         {"cos",   1, cos},
18         {"cosh",  1, cosh},
19         {"exp",   1, exp},
20         {"expm1", 1, expm1},
21         {"floor", 1, floor},
22         {"fmod",  2, fmod},
23         {"hypot", 2, hypot},
24         {"log",   1, log},
25         {"log10", 1, log10},
26         {"log1p", 1, log1p},
27         {"log2",  1, log2},
28         {"pow",   2, pow},
29         {"sin",   1, sin},
30         {"sinh",  1, sinh},
31         {"sqrt",  1, sqrt},
32         {"tan",   1, tan},
33         {"tanh",  1, tanh},
34 };
35 static int nfuncs = sizeof funcs / sizeof *funcs;
36
37 struct test {
38         struct func *func;
39         int round;
40         int except;
41         int exceptopt;
42         double in1;
43         double in2;
44         double out;
45 };
46
47 static double tod(uint32_t *a) {
48         union { double x; uint64_t n; } u;
49
50         u.n = ((uint64_t)a[0] << 32) | a[1];
51         return u.x;
52 }
53
54 int scantest(struct test *t) {
55         char name[32];
56         char round[32];
57         char cmp[32];
58         char except[32];
59         char buf[512];
60         uint32_t a[6];
61         int i;
62
63         if (!fgets(buf, sizeof buf, stdin))
64                 return 0;
65
66         if (sscanf(buf, "%30s %30s %30s %30s %x %x %x %x %x %x",
67              name, round, cmp, except, a+0, a+1, a+2, a+3, a+4, a+5) < 8)
68                 return 0;
69
70         for (i = 0; i < nfuncs; i++)
71                 if (strcmp(funcs[i].name, name) == 0)
72                         break;
73         if (i == nfuncs)
74                 return 0;
75         t->func = funcs+i;
76         t->round = round[0] == 'n';
77
78         t->except = t->exceptopt = 0;
79         for (i = 0; i < sizeof except; i++) {
80                 int f;
81
82                 if (except[i] == '\0')
83                         break;
84                 switch (except[i]) {
85                 case 'v': f = FE_INVALID; break;
86                 case 'x': f = FE_INEXACT; break;
87                 case 'o': f = FE_OVERFLOW; break;
88                 case 'u': f = FE_UNDERFLOW; break;
89                 case 'd': f = FE_DIVBYZERO; break;
90                 default:
91                         continue;
92                 }
93                 if (i > 0 && except[i-1]=='?')
94                         t->exceptopt |= f;
95                 else
96                         t->except |= f;
97         }
98
99         t->in1 = tod(a);
100         t->in2 = 0;
101         if (t->func->args == 1) {
102                 t->out = tod(a+2);
103         } else {
104                 t->in2 = tod(a+2);
105                 t->out = tod(a+4);
106         }
107
108         if (strcmp(cmp, "uo") == 0)
109                 t->out = 0.0/0.0;
110         return 1;
111 }
112
113 int main(){
114         struct test t;
115         union {double x; uint64_t n;} got, want;
116         int64_t k;
117         int n=0, err=0, err2=0, err99=0;
118
119         while (!feof(stdin)) {
120                 if(!scantest(&t)) {
121 //                      puts("scan fail");
122                         continue;
123                 }
124                 if (!t.round)
125                         continue;
126                 if (t.func->args == 1)
127                         got.x = t.func->f(t.in1);
128                 else
129                         got.x = t.func->f(t.in1, t.in2);
130                 want.x = t.out;
131
132                 if (got.n != want.n &&
133                     (!isnan(got.x) || !isnan(want.x))) {
134                         err++;
135                         // hack: mostly error in ulp
136                         k = (int64_t)(got.n - want.n);
137                         if (k >= 100)
138                                 k = 99;
139                         if (k <= -100)
140                                 k = -99;
141                         if (k > 1 || k < -1)
142                                 err2++;
143                         if (k == 99 || k == -99)
144                                 err99++;
145                         printf("%3d ulp %16llx %16llx   %s %a %a %a %a\n",
146                           (int)k, want.n, got.n, t.func->name, t.in1, t.in2, t.out, got.x);
147                 }
148                 n++;
149         }
150         printf("all: %d fail: %d failbad: %d failepic: %d\n", n, err, err2, err99);
151         return 0;
152 }