1#include <stdio.h> 2#include <math.h> 3 4#define T(a,b) {__LINE__, a, b}, 5#define length(a) (sizeof(a)/sizeof*(a)) 6 7static struct { 8 int line; 9 float f; 10 int class; 11} tf[] = { 12 T(0.0/0.0, FP_NAN) 13 T(-0.0/0.0, FP_NAN) 14 T(1/0.0, FP_INFINITE) 15 T(-1/0.0, FP_INFINITE) 16 T(0x1.ffffp127, FP_NORMAL) 17 T(-0x1.ffffp127, FP_NORMAL) 18 T(0x1p-127, FP_SUBNORMAL) 19 T(-0x1p-127, FP_SUBNORMAL) 20 T(0.0, FP_ZERO) 21 T(-0.0, FP_ZERO) 22 T(3.14, FP_NORMAL) 23 T(-42, FP_NORMAL) 24}; 25 26static struct { 27 int line; 28 double f; 29 int class; 30} td[] = { 31 T(0.0/0.0, FP_NAN) 32 T(-0.0/0.0, FP_NAN) 33 T(1/0.0, FP_INFINITE) 34 T(-1/0.0, FP_INFINITE) 35 T(0x1.ffffp1023, FP_NORMAL) 36 T(-0x1.ffffp1023, FP_NORMAL) 37 T(0x1p-1023, FP_SUBNORMAL) 38 T(-0x1p-1023, FP_SUBNORMAL) 39 T(0.0, FP_ZERO) 40 T(-0.0, FP_ZERO) 41 T(3.14, FP_NORMAL) 42 T(-42, FP_NORMAL) 43}; 44 45static struct { 46 int line; 47 long double f; 48 int class; 49} tl[] = { 50 T(0.0/0.0, FP_NAN) 51 T(-0.0/0.0, FP_NAN) 52 T(1/0.0, FP_INFINITE) 53 T(-1/0.0, FP_INFINITE) 54#if LDBL_MAX_EXP==16384 55 T(0x1.ffffp16383L, FP_NORMAL) 56 T(-0x1.ffffp16383L, FP_NORMAL) 57 T(0x1p-16383L, FP_SUBNORMAL) 58 T(-0x1p-16383L, FP_SUBNORMAL) 59#elif LDBL_MAX_EXP==1024 60 T(0x1.ffffp1023L, FP_NORMAL) 61 T(-0x1.ffffp1023L, FP_NORMAL) 62 T(0x1p-1023L, FP_SUBNORMAL) 63 T(-0x1p-1023L, FP_SUBNORMAL) 64#endif 65 T(0.0, FP_ZERO) 66 T(-0.0, FP_ZERO) 67 T(3.14, FP_NORMAL) 68 T(-42, FP_NORMAL) 69}; 70 71static char *strclass(int c) 72{ 73#define C(n) case n: return #n; 74 switch (c) { 75 C(FP_NAN) 76 C(FP_INFINITE) 77 C(FP_ZERO) 78 C(FP_SUBNORMAL) 79 C(FP_NORMAL) 80 } 81 return "invalid"; 82} 83 84#define error(t,c) err++, printf("%s:%d: (at line %d) %La has class %d (%s), but %s returns %d\n", \ 85 __FILE__, __LINE__, t.line, (long double)t.f, t.class, strclass(t.class), #c, c(t.f)) 86 87int main() 88{ 89 int i; 90 int err = 0; 91 92 for (i = 0; i < length(tf); i++) { 93 if (fpclassify(tf[i].f) != tf[i].class) 94 error(tf[i], fpclassify); 95 if (!!isinf(tf[i].f) != (tf[i].class == FP_INFINITE)) 96 error(tf[i], isinf); 97 if (!!isnan(tf[i].f) != (tf[i].class == FP_NAN)) 98 error(tf[i], isnan); 99 if (!!isnormal(tf[i].f) != (tf[i].class == FP_NORMAL)) 100 error(tf[i], isnormal); 101 if (!!isfinite(tf[i].f) != (tf[i].class > FP_INFINITE)) 102 error(tf[i], isfinite); 103 } 104 105 for (i = 0; i < length(td); i++) { 106 if (fpclassify(td[i].f) != td[i].class) 107 error(td[i], fpclassify); 108 if (!!isinf(td[i].f) != (td[i].class == FP_INFINITE)) 109 error(td[i], isinf); 110 if (!!isnan(td[i].f) != (td[i].class == FP_NAN)) 111 error(td[i], isnan); 112 if (!!isnormal(td[i].f) != (td[i].class == FP_NORMAL)) 113 error(td[i], isnormal); 114 if (!!isfinite(td[i].f) != (td[i].class > FP_INFINITE)) 115 error(td[i], isfinite); 116 } 117 118 for (i = 0; i < length(tl); i++) { 119 if (fpclassify(tl[i].f) != tl[i].class) 120 error(tl[i], fpclassify); 121 if (!!isinf(tl[i].f) != (tl[i].class == FP_INFINITE)) 122 error(tl[i], isinf); 123 if (!!isnan(tl[i].f) != (tl[i].class == FP_NAN)) 124 error(tl[i], isnan); 125 if (!!isnormal(tl[i].f) != (tl[i].class == FP_NORMAL)) 126 error(tl[i], isnormal); 127 if (!!isfinite(tl[i].f) != (tl[i].class > FP_INFINITE)) 128 error(tl[i], isfinite); 129 } 130 131 return !!err; 132} 133