fltest.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /* fltest.c
  2. * Test program for floor(), frexp(), ldexp()
  3. */
  4. /*
  5. Cephes Math Library Release 2.1: December, 1988
  6. Copyright 1984, 1987, 1988 by Stephen L. Moshier
  7. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  8. */
  9. #include <math.h>
  10. extern double MACHEP;
  11. #define UTH -1023
  12. main()
  13. {
  14. double x, y, y0, z, f, x00, y00;
  15. int i, j, k, e, e0;
  16. int errfr, errld, errfl, underexp, err, errth, e00;
  17. double frexp(), ldexp(), floor();
  18. /*
  19. if( 1 )
  20. goto flrtst;
  21. */
  22. printf( "Testing frexp() and ldexp().\n" );
  23. errfr = 0;
  24. errld = 0;
  25. underexp = 0;
  26. f = 1.0;
  27. x00 = 2.0;
  28. y00 = 0.5;
  29. e00 = 2;
  30. for( j=0; j<20; j++ )
  31. {
  32. if( j == 10 )
  33. {
  34. f = 1.0;
  35. x00 = 2.0;
  36. e00 = 1;
  37. /* Find 2**(2**10) / 2 */
  38. #ifdef DEC
  39. for( i=0; i<5; i++ )
  40. #else
  41. for( i=0; i<9; i++ )
  42. #endif
  43. {
  44. x00 *= x00;
  45. e00 += e00;
  46. }
  47. y00 = x00/2.0;
  48. x00 = x00 * y00;
  49. e00 += e00;
  50. y00 = 0.5;
  51. }
  52. x = x00 * f;
  53. y0 = y00 * f;
  54. e0 = e00;
  55. for( i=0; i<2200; i++ )
  56. {
  57. x /= 2.0;
  58. e0 -= 1;
  59. if( x == 0.0 )
  60. {
  61. if( f == 1.0 )
  62. underexp = e0;
  63. y0 = 0.0;
  64. e0 = 0;
  65. }
  66. y = frexp( x, &e );
  67. if( (e0 < -1023) && (e != e0) )
  68. {
  69. if( e == (e0 - 1) )
  70. {
  71. e += 1;
  72. y /= 2.0;
  73. }
  74. if( e == (e0 + 1) )
  75. {
  76. e -= 1;
  77. y *= 2.0;
  78. }
  79. }
  80. err = y - y0;
  81. if( y0 != 0.0 )
  82. err /= y0;
  83. if( err < 0.0 )
  84. err = -err;
  85. if( e0 > -1023 )
  86. errth = 0.0;
  87. else
  88. {/* Denormal numbers may have rounding errors */
  89. if( e0 == -1023 )
  90. {
  91. errth = 2.0 * MACHEP;
  92. }
  93. else
  94. {
  95. errth *= 2.0;
  96. }
  97. }
  98. if( (x != 0.0) && ((err > errth) || (e != e0)) )
  99. {
  100. printf( "Test %d: ", j+1 );
  101. printf( " frexp( %.15e) =?= %.15e * 2**%d;", x, y, e );
  102. printf( " should be %.15e * 2**%d\n", y0, e0 );
  103. errfr += 1;
  104. }
  105. y = ldexp( x, 1-e0 );
  106. err = y - 1.0;
  107. if( err < 0.0 )
  108. err = -err;
  109. if( (err > errth) && ((x == 0.0) && (y != 0.0)) )
  110. {
  111. printf( "Test %d: ", j+1 );
  112. printf( "ldexp( %.15e, %d ) =?= %.15e;", x, 1-e0, y );
  113. if( x != 0.0 )
  114. printf( " should be %.15e\n", f );
  115. else
  116. printf( " should be %.15e\n", 0.0 );
  117. errld += 1;
  118. }
  119. if( x == 0.0 )
  120. {
  121. break;
  122. }
  123. }
  124. f = f * 1.08005973889;
  125. }
  126. x = 2.22507385850720138309e-308;
  127. for (i = 0; i < 52; i++)
  128. {
  129. y = ldexp (x, -i);
  130. z = ldexp (y, i);
  131. if (x != z)
  132. {
  133. printf ("x %.16e, i %d, y %.16e, z %.16e\n", x, i, y, z);
  134. errld += 1;
  135. }
  136. }
  137. if( (errld == 0) && (errfr == 0) )
  138. {
  139. printf( "No errors found.\n" );
  140. }
  141. flrtst:
  142. printf( "Testing floor().\n" );
  143. errfl = 0;
  144. f = 1.0/MACHEP;
  145. x00 = 1.0;
  146. for( j=0; j<57; j++ )
  147. {
  148. x = x00 - 1.0;
  149. for( i=0; i<128; i++ )
  150. {
  151. y = floor(x);
  152. if( y != x )
  153. {
  154. flierr( x, y, j );
  155. errfl += 1;
  156. }
  157. /* Warning! the if() statement is compiler dependent,
  158. * since x-0.49 may be held in extra precision accumulator
  159. * so would never compare equal to x! The subroutine call
  160. * y = floor() forces z to be stored as a double and reloaded
  161. * for the if() statement.
  162. */
  163. z = x - 0.49;
  164. y = floor(z);
  165. if( z == x )
  166. break;
  167. if( y != (x - 1.0) )
  168. {
  169. flierr( z, y, j );
  170. errfl += 1;
  171. }
  172. z = x + 0.49;
  173. y = floor(z);
  174. if( z != x )
  175. {
  176. if( y != x )
  177. {
  178. flierr( z, y, j );
  179. errfl += 1;
  180. }
  181. }
  182. x = -x;
  183. y = floor(x);
  184. if( z != x )
  185. {
  186. if( y != x )
  187. {
  188. flierr( x, y, j );
  189. errfl += 1;
  190. }
  191. }
  192. z = x + 0.49;
  193. y = floor(z);
  194. if( z != x )
  195. {
  196. if( y != x )
  197. {
  198. flierr( z, y, j );
  199. errfl += 1;
  200. }
  201. }
  202. z = x - 0.49;
  203. y = floor(z);
  204. if( z != x )
  205. {
  206. if( y != (x - 1.0) )
  207. {
  208. flierr( z, y, j );
  209. errfl += 1;
  210. }
  211. }
  212. x = -x;
  213. x += 1.0;
  214. }
  215. x00 = x00 + x00;
  216. }
  217. y = floor(0.0);
  218. if( y != 0.0 )
  219. {
  220. flierr( 0.0, y, 57 );
  221. errfl += 1;
  222. }
  223. y = floor(-0.0);
  224. if( y != 0.0 )
  225. {
  226. flierr( -0.0, y, 58 );
  227. errfl += 1;
  228. }
  229. y = floor(-1.0);
  230. if( y != -1.0 )
  231. {
  232. flierr( -1.0, y, 59 );
  233. errfl += 1;
  234. }
  235. y = floor(-0.1);
  236. if( y != -1.0 )
  237. {
  238. flierr( -0.1, y, 60 );
  239. errfl += 1;
  240. }
  241. if( errfl == 0 )
  242. printf( "No errors found in floor().\n" );
  243. }
  244. flierr( x, y, k )
  245. double x, y;
  246. int k;
  247. {
  248. printf( "Test %d: ", k+1 );
  249. printf( "floor(%.15e) =?= %.15e\n", x, y );
  250. }