1 /* Determine some float parameters, much like gcc's "enquire.c". */
2 /* Bruno Haible 24.8.1996 */
4 /* This program expects to be compiled by an ANSI C or C++ compiler. */
12 typedef long double ldouble;
14 static void header (void)
16 printf("/* Rounding modes, for use below */\n");
17 printf("#define rounds_to_nearest 0 /* 0.5 ulp */\n");
18 printf("#define rounds_to_zero 1 /* 1 ulp */\n");
19 printf("#define rounds_to_infinity 2 /* 1 ulp */\n");
20 printf("#define rounds_to_minus_infinity 3 /* 1 ulp */\n");
24 #define check(type,typeprefix,typestr,equalfn,mainfn) \
25 static boolean equalfn (volatile type* x, volatile type* y); \
26 static void mainfn (void) \
29 int epsilon_bits = -1; \
30 int negepsilon_bits = -1; \
31 { type x = 1.0; type y; type z; \
32 for (y = 1.0; ; y = 0.5*y) \
33 { z = x + y; if (equalfn(&x,&z)) break; \
34 z = z - x; if (!equalfn(&y,&z)) break; \
37 { type x = 1.0; type y; type z; \
38 for (y = -1.0; ; y = 0.5*y) \
39 { z = x + y; if (equalfn(&x,&z)) break; \
40 z = z - x; if (!equalfn(&y,&z)) break; \
43 printf("/* Properties of type `%s': */\n",typestr); \
44 printf("/* Largest n for which 1+2^(-n) is exactly represented is %d. */\n",epsilon_bits); \
45 printf("/* Largest n for which 1-2^(-n) is exactly represented is %d. */\n",negepsilon_bits); \
46 if (negepsilon_bits <= epsilon_bits) \
47 { printf("#error \"No exponent jump at 1.0 for type %s!\"\n",typestr); \
51 { if (negepsilon_bits > epsilon_bits+1) \
52 printf("/* Base for type `%s' is 2^%d\n",typestr,negepsilon_bits-epsilon_bits); \
53 mant_bits = epsilon_bits+1; \
54 printf("#define %s_mant_bits %d\n",typeprefix,mant_bits); \
56 { int i; type x, y1, y2, ys1, ys2, z1, z2, zs1, zs2; \
57 x = 1.0; for (i = 0; i < epsilon_bits; i++) { x = 0.5*x; } \
58 y1 = 1.0 + 5.0*x; y2 = 1.0 + 6.0*x; \
59 ys1 = 1.0 + 5.4*x; ys2 = 1.0 + 5.6*x; \
60 z1 = -1.0 + (-5.0)*x; z2 = -1.0 + (-6.0)*x; \
61 zs1 = -1.0 + (-5.4)*x; zs2 = -1.0 + (-5.6)*x; \
62 if (equalfn(&ys1,&y1) && equalfn(&ys2,&y2) && equalfn(&zs1,&z1) && equalfn(&zs2,&z2)) \
63 printf("#define %s_rounds rounds_to_nearest\n",typeprefix); \
64 else if (equalfn(&ys1,&y1) && equalfn(&ys2,&y1) && equalfn(&zs1,&z1) && equalfn(&zs2,&z1)) \
65 printf("#define %s_rounds rounds_to_zero\n",typeprefix); \
66 else if (equalfn(&ys1,&y2) && equalfn(&ys2,&y2) && equalfn(&zs1,&z1) && equalfn(&zs2,&z1)) \
67 printf("#define %s_rounds rounds_to_infinity\n",typeprefix); \
68 else if (equalfn(&ys1,&y1) && equalfn(&ys2,&y1) && equalfn(&zs1,&z2) && equalfn(&zs2,&z2)) \
69 printf("#define %s_rounds rounds_to_minus_infinity\n",typeprefix); \
71 printf("#error \"Unknown rounding mode for type %s!\"\n",typestr); \
75 static boolean equalfn (volatile type* x, volatile type* y) \
80 check(float,"float","float",equal_float,main_float)
81 check(double,"double","double",equal_double,main_double)
82 check(ldouble,"long_double","long double",equal_ldouble,main_ldouble)
84 /* Some systems (arm/linux) store doubles as little endian but with higher
85 * and lower word reversed. */
86 static void flipped_double (void)
88 typedef struct { unsigned lo, hi; } dfloat;
89 union { dfloat eksplicit; double machine_double; } x;
91 dfloat test = x.eksplicit;
92 if (test.lo==0 && test.hi!=0) {
93 printf("#define double_wordorder_bigendian_p 0\n");
94 } else if (test.lo!=0 && test.hi==0) {
95 printf("#define double_wordorder_bigendian_p 1\n");
97 /* Dazed and confused! Better not define anything.
98 * Code should rely on CL_CPU_BIG_ENDIAN_P instead. */
103 int main(int argc, char *argv[])
104 { if (freopen(argc==1 ? "conftest.h" : argv[1], "w", stdout) == NULL) return 1;
111 if (ferror(stdout) || fclose(stdout)) return 1;