You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.8 KiB

25 years ago
  1. /* Determine some float parameters, much like gcc's "enquire.c". */
  2. /* Bruno Haible 24.8.1996 */
  3. /* This program expects to be compiled by an ANSI C or C++ compiler. */
  4. #include <stdio.h>
  5. #if !(defined(__STDC__) || defined(__cplusplus))
  6. /* Only for use in function parameter lists and as function return type. */
  7. #define void
  8. #endif
  9. typedef int boolean;
  10. #define TRUE 1
  11. #define FALSE 0
  12. #ifdef HAVE_LONGDOUBLE
  13. typedef long double ldouble;
  14. #endif
  15. static void header (void)
  16. {
  17. printf("/* Rounding modes, for use below */\n");
  18. printf("#define rounds_to_nearest 0 /* 0.5 ulp */\n");
  19. printf("#define rounds_to_zero 1 /* 1 ulp */\n");
  20. printf("#define rounds_to_infinity 2 /* 1 ulp */\n");
  21. printf("#define rounds_to_minus_infinity 3 /* 1 ulp */\n");
  22. printf("\n");
  23. }
  24. #define check(type,typeprefix,typestr,equalfn,mainfn) \
  25. static boolean equalfn (type* x, type* y); \
  26. static void mainfn (void) \
  27. { \
  28. int mant_bits; \
  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; \
  35. epsilon_bits++; \
  36. } } \
  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; \
  41. negepsilon_bits++; \
  42. } } \
  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); \
  48. mant_bits = -1; \
  49. } \
  50. else \
  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); \
  55. } \
  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); \
  70. else \
  71. printf("#error \"Unknown rounding mode for type %s!\"\n",typestr); \
  72. } \
  73. printf("\n"); \
  74. } \
  75. static boolean equalfn (type* x, type* y) { return *x == *y; } \
  76. check(float,"float","float",equal_float,main_float)
  77. check(double,"double","double",equal_double,main_double)
  78. #ifdef HAVE_LONGDOUBLE
  79. check(ldouble,"long_double","long double",equal_ldouble,main_ldouble)
  80. #endif
  81. int main()
  82. {
  83. header();
  84. main_float();
  85. main_double();
  86. #ifdef HAVE_LONGDOUBLE
  87. main_ldouble();
  88. #endif
  89. #if defined(__cplusplus)
  90. if (ferror(stdout)) return 1;
  91. return 0;
  92. #else
  93. if (ferror(stdout)) { exit(1); }
  94. exit(0);
  95. #endif
  96. }