1570af302Sopenharmony_ci#include <stdio.h>
2570af302Sopenharmony_ci#include <math.h>
3570af302Sopenharmony_ci
4570af302Sopenharmony_ci#define T(a,b) {__LINE__, a, b},
5570af302Sopenharmony_ci#define length(a) (sizeof(a)/sizeof*(a))
6570af302Sopenharmony_ci
7570af302Sopenharmony_cistatic struct {
8570af302Sopenharmony_ci	int line;
9570af302Sopenharmony_ci	float f;
10570af302Sopenharmony_ci	int class;
11570af302Sopenharmony_ci} tf[] = {
12570af302Sopenharmony_ci	T(0.0/0.0, FP_NAN)
13570af302Sopenharmony_ci	T(-0.0/0.0, FP_NAN)
14570af302Sopenharmony_ci	T(1/0.0, FP_INFINITE)
15570af302Sopenharmony_ci	T(-1/0.0, FP_INFINITE)
16570af302Sopenharmony_ci	T(0x1.ffffp127, FP_NORMAL)
17570af302Sopenharmony_ci	T(-0x1.ffffp127, FP_NORMAL)
18570af302Sopenharmony_ci	T(0x1p-127, FP_SUBNORMAL)
19570af302Sopenharmony_ci	T(-0x1p-127, FP_SUBNORMAL)
20570af302Sopenharmony_ci	T(0.0, FP_ZERO)
21570af302Sopenharmony_ci	T(-0.0, FP_ZERO)
22570af302Sopenharmony_ci	T(3.14, FP_NORMAL)
23570af302Sopenharmony_ci	T(-42, FP_NORMAL)
24570af302Sopenharmony_ci};
25570af302Sopenharmony_ci
26570af302Sopenharmony_cistatic struct {
27570af302Sopenharmony_ci	int line;
28570af302Sopenharmony_ci	double f;
29570af302Sopenharmony_ci	int class;
30570af302Sopenharmony_ci} td[] = {
31570af302Sopenharmony_ci	T(0.0/0.0, FP_NAN)
32570af302Sopenharmony_ci	T(-0.0/0.0, FP_NAN)
33570af302Sopenharmony_ci	T(1/0.0, FP_INFINITE)
34570af302Sopenharmony_ci	T(-1/0.0, FP_INFINITE)
35570af302Sopenharmony_ci	T(0x1.ffffp1023, FP_NORMAL)
36570af302Sopenharmony_ci	T(-0x1.ffffp1023, FP_NORMAL)
37570af302Sopenharmony_ci	T(0x1p-1023, FP_SUBNORMAL)
38570af302Sopenharmony_ci	T(-0x1p-1023, FP_SUBNORMAL)
39570af302Sopenharmony_ci	T(0.0, FP_ZERO)
40570af302Sopenharmony_ci	T(-0.0, FP_ZERO)
41570af302Sopenharmony_ci	T(3.14, FP_NORMAL)
42570af302Sopenharmony_ci	T(-42, FP_NORMAL)
43570af302Sopenharmony_ci};
44570af302Sopenharmony_ci
45570af302Sopenharmony_cistatic struct {
46570af302Sopenharmony_ci	int line;
47570af302Sopenharmony_ci	long double f;
48570af302Sopenharmony_ci	int class;
49570af302Sopenharmony_ci} tl[] = {
50570af302Sopenharmony_ci	T(0.0/0.0, FP_NAN)
51570af302Sopenharmony_ci	T(-0.0/0.0, FP_NAN)
52570af302Sopenharmony_ci	T(1/0.0, FP_INFINITE)
53570af302Sopenharmony_ci	T(-1/0.0, FP_INFINITE)
54570af302Sopenharmony_ci#if LDBL_MAX_EXP==16384
55570af302Sopenharmony_ci	T(0x1.ffffp16383L, FP_NORMAL)
56570af302Sopenharmony_ci	T(-0x1.ffffp16383L, FP_NORMAL)
57570af302Sopenharmony_ci	T(0x1p-16383L, FP_SUBNORMAL)
58570af302Sopenharmony_ci	T(-0x1p-16383L, FP_SUBNORMAL)
59570af302Sopenharmony_ci#elif LDBL_MAX_EXP==1024
60570af302Sopenharmony_ci	T(0x1.ffffp1023L, FP_NORMAL)
61570af302Sopenharmony_ci	T(-0x1.ffffp1023L, FP_NORMAL)
62570af302Sopenharmony_ci	T(0x1p-1023L, FP_SUBNORMAL)
63570af302Sopenharmony_ci	T(-0x1p-1023L, FP_SUBNORMAL)
64570af302Sopenharmony_ci#endif
65570af302Sopenharmony_ci	T(0.0, FP_ZERO)
66570af302Sopenharmony_ci	T(-0.0, FP_ZERO)
67570af302Sopenharmony_ci	T(3.14, FP_NORMAL)
68570af302Sopenharmony_ci	T(-42, FP_NORMAL)
69570af302Sopenharmony_ci};
70570af302Sopenharmony_ci
71570af302Sopenharmony_cistatic char *strclass(int c)
72570af302Sopenharmony_ci{
73570af302Sopenharmony_ci#define C(n) case n: return #n;
74570af302Sopenharmony_ci	switch (c) {
75570af302Sopenharmony_ci	C(FP_NAN)
76570af302Sopenharmony_ci	C(FP_INFINITE)
77570af302Sopenharmony_ci	C(FP_ZERO)
78570af302Sopenharmony_ci	C(FP_SUBNORMAL)
79570af302Sopenharmony_ci	C(FP_NORMAL)
80570af302Sopenharmony_ci	}
81570af302Sopenharmony_ci	return "invalid";
82570af302Sopenharmony_ci}
83570af302Sopenharmony_ci
84570af302Sopenharmony_ci#define error(t,c) err++, printf("%s:%d: (at line %d) %La has class %d (%s), but %s returns %d\n", \
85570af302Sopenharmony_ci	__FILE__, __LINE__, t.line, (long double)t.f, t.class, strclass(t.class), #c, c(t.f))
86570af302Sopenharmony_ci
87570af302Sopenharmony_ciint main()
88570af302Sopenharmony_ci{
89570af302Sopenharmony_ci	int i;
90570af302Sopenharmony_ci	int err = 0;
91570af302Sopenharmony_ci
92570af302Sopenharmony_ci	for (i = 0; i < length(tf); i++) {
93570af302Sopenharmony_ci		if (fpclassify(tf[i].f) != tf[i].class)
94570af302Sopenharmony_ci			error(tf[i], fpclassify);
95570af302Sopenharmony_ci		if (!!isinf(tf[i].f) != (tf[i].class == FP_INFINITE))
96570af302Sopenharmony_ci			error(tf[i], isinf);
97570af302Sopenharmony_ci		if (!!isnan(tf[i].f) != (tf[i].class == FP_NAN))
98570af302Sopenharmony_ci			error(tf[i], isnan);
99570af302Sopenharmony_ci		if (!!isnormal(tf[i].f) != (tf[i].class == FP_NORMAL))
100570af302Sopenharmony_ci			error(tf[i], isnormal);
101570af302Sopenharmony_ci		if (!!isfinite(tf[i].f) != (tf[i].class > FP_INFINITE))
102570af302Sopenharmony_ci			error(tf[i], isfinite);
103570af302Sopenharmony_ci	}
104570af302Sopenharmony_ci
105570af302Sopenharmony_ci	for (i = 0; i < length(td); i++) {
106570af302Sopenharmony_ci		if (fpclassify(td[i].f) != td[i].class)
107570af302Sopenharmony_ci			error(td[i], fpclassify);
108570af302Sopenharmony_ci		if (!!isinf(td[i].f) != (td[i].class == FP_INFINITE))
109570af302Sopenharmony_ci			error(td[i], isinf);
110570af302Sopenharmony_ci		if (!!isnan(td[i].f) != (td[i].class == FP_NAN))
111570af302Sopenharmony_ci			error(td[i], isnan);
112570af302Sopenharmony_ci		if (!!isnormal(td[i].f) != (td[i].class == FP_NORMAL))
113570af302Sopenharmony_ci			error(td[i], isnormal);
114570af302Sopenharmony_ci		if (!!isfinite(td[i].f) != (td[i].class > FP_INFINITE))
115570af302Sopenharmony_ci			error(td[i], isfinite);
116570af302Sopenharmony_ci	}
117570af302Sopenharmony_ci
118570af302Sopenharmony_ci	for (i = 0; i < length(tl); i++) {
119570af302Sopenharmony_ci		if (fpclassify(tl[i].f) != tl[i].class)
120570af302Sopenharmony_ci			error(tl[i], fpclassify);
121570af302Sopenharmony_ci		if (!!isinf(tl[i].f) != (tl[i].class == FP_INFINITE))
122570af302Sopenharmony_ci			error(tl[i], isinf);
123570af302Sopenharmony_ci		if (!!isnan(tl[i].f) != (tl[i].class == FP_NAN))
124570af302Sopenharmony_ci			error(tl[i], isnan);
125570af302Sopenharmony_ci		if (!!isnormal(tl[i].f) != (tl[i].class == FP_NORMAL))
126570af302Sopenharmony_ci			error(tl[i], isnormal);
127570af302Sopenharmony_ci		if (!!isfinite(tl[i].f) != (tl[i].class > FP_INFINITE))
128570af302Sopenharmony_ci			error(tl[i], isfinite);
129570af302Sopenharmony_ci	}
130570af302Sopenharmony_ci
131570af302Sopenharmony_ci	return !!err;
132570af302Sopenharmony_ci}
133