home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / libsrc87 / frexp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-30  |  2.2 KB  |  111 lines

  1. #define __normdf norm    /* for now */
  2. /*
  3.  * double frexp(value, eptr)
  4.  * double value;
  5.  * int *eptr;
  6.  *
  7.  * returns significand (|significand| < 1)
  8.  *       in *eptr returns n such that value = significand * 2**n
  9.  *
  10.  * ++jrb    bammi@dsrgsun.ces.cwru.edu
  11.  *
  12.  */
  13. #include "flonum.h"
  14.  
  15. #define BIAS 1023
  16. #define B1   1022
  17.  
  18. double frexp(value, eptr)
  19. double value;
  20. #ifdef SHORTLIB
  21. short *eptr;
  22. #else
  23. int *eptr;
  24. #endif
  25. {
  26.     struct bitdouble *res = (struct bitdouble *) &value;
  27.     unsigned int expo, sign;
  28. #ifdef __STDC__
  29.     double __normdf( double, int, int, int );
  30. #else
  31.     extern double __normdf();
  32. #endif
  33.     
  34.     expo = res->exp;
  35.     sign = res->sign;
  36.     res->exp = 0;
  37.     res->sign = 0;
  38.     *eptr = expo - B1;
  39.     if(expo != 0)
  40.     res->exp = 1;    /* put in hidden bit */
  41.     else
  42.     if((res->mant1 == 0) && (res->mant2 == 0))
  43.     {
  44.         *eptr = 0;
  45.         return 0.0;    /* no point in normalizing (exp will be wrong) */
  46.     }
  47.  
  48.     return __normdf(value, B1, sign, 0);
  49. }
  50.  
  51. #ifdef TEST /* combined test for frexp and ldexp */
  52.     /* 32 bit ints for this test please */
  53.  
  54. #ifdef __MSHORT__
  55. #error "please run this test in 32 bit int mode"
  56. #endif
  57.  
  58. #include <stdio.h>
  59.  
  60. #define NTEST    100000L
  61. #define MAXRAND 0x7fffffffL    /* assuming 32 bit ints */
  62. #define ABS(X)    ( (X < 0) ? (-X) : X )
  63. extern long rand();
  64.  
  65. int main()
  66. {
  67.     double sig, e, expected, result, max_abs_err;
  68.     int twoexp;
  69.     register long i;
  70.     register long errs = 0;
  71.     register int s;
  72. #ifdef __STDC__
  73.     double ldexp(double, int);
  74.     double frexp(double, int *);
  75. #else
  76.     extern double ldexp();
  77.     extern double frexp();
  78. #endif
  79.  
  80.     max_abs_err = 0.0;
  81.     for(i = 0; i < NTEST; i++)
  82.     {
  83.     expected = ((double)(s = rand()) + (double)rand())/(double)(MAXRAND);
  84.     if(s > (MAXRAND >> 1)) expected = -expected;
  85.  
  86.     sig = frexp(expected, &twoexp);
  87.     if(ABS(sig) >= 1.0)
  88.     {
  89.         printf("sig > 1, %.4e: %.4e  %d\n", expected, sig, twoexp);
  90.         errs++;
  91.         continue;
  92.     }
  93.     
  94.     result = ldexp(sig, twoexp);
  95.     
  96.     e = (expected == 0.0) ? result : (result - expected)/expected;
  97.     if(e < 0) e = (-e);
  98.     if(e > 1.0e-6)
  99.     {
  100.         printf("%.8e: %.8e  E %.8e\n",
  101.            expected, result, e);
  102.         errs++;
  103.     }
  104.     if (e > max_abs_err) max_abs_err = e;
  105.     }
  106.     
  107.     printf("%ld Error(s), Max abs err %.14e\n", errs, max_abs_err);
  108.     return errs;
  109. }
  110. #endif /* TEST */
  111.