home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / libsrc87 / modf_c.old < prev    next >
Encoding:
Text File  |  1993-07-30  |  2.7 KB  |  153 lines

  1. /*
  2.  * double modf(value, iptr)
  3.  * double value;
  4.  * double *iptr;
  5.  *
  6.  * returns fractional part of value
  7.  *       in *iptr rets. the integral part such that (*iptr + modf) == value
  8.  *
  9.  * ++jrb    bammi@dsrgsun.ces.cwru.edu
  10.  */
  11. #include "flonum.h"
  12.  
  13. /*
  14.  * extract integral portion of an Ieee double -- return it as a double
  15.  * ++jrb
  16.  */
  17.  
  18. #define BIAS  1023
  19. #define B1    1022
  20. #define MANT1 21
  21. #define MANT2 32
  22. #define MASK  0xFFFFFFFFL
  23. struct ldouble {
  24.     unsigned long hi, lo;
  25. };
  26. static double extract_int(val)
  27. double val;
  28. {
  29.     struct bitdouble *bd = (struct bitdouble *)&val;
  30.     struct ldouble *l    = (struct ldouble *)&val;
  31.     register int ex = bd->exp - BIAS, sign = bd->sign;
  32. #ifdef __STDC__
  33.     double norm( double, int, int, int );
  34. #else
  35.     extern double norm();
  36. #endif
  37.     
  38.     /* trivial case */
  39.     if(ex < 0) return 0.0;
  40.     
  41.     bd->sign = 0;
  42.     bd->exp  = 1;  /* hidden bit */
  43.     /* exponent <= # of bits in mant1 */
  44.     if(ex <= MANT1)
  45.     {
  46.     l->hi &= (MASK << (MANT1 - ex));
  47.     l->lo = 0L;
  48.     }
  49.     else /* if (ex <= (MANT1 + MANT2)) */
  50.     {
  51.     l->lo &= (MASK << ((MANT1 + MANT2) - ex));
  52.     }
  53.     /* else the value is too big */
  54.  
  55.     return norm(val, ex+BIAS, sign, 0);
  56. }
  57.  
  58.  
  59. double modf(value, iptr)
  60. double value, *iptr;
  61. {
  62.     double integral;
  63.     
  64.     if((-1.0 < value) && (value < 1.0))
  65.     {
  66.     *iptr = 0.0;
  67.     return value;
  68.     }
  69.  
  70.     integral = extract_int(value);
  71.     *iptr = integral;
  72.     return value - integral;
  73. }
  74.  
  75. #ifdef TEST1
  76. #ifndef TEST
  77. #define TEST
  78. #endif
  79. #endif
  80.  
  81. #ifdef TEST
  82.  
  83. #define  MAXRAND 0x7fffffffL
  84.  
  85. #ifndef TEST1
  86. #define TESTSIZE 10240
  87. double testin[TESTSIZE];
  88.  
  89. static void init()
  90. {
  91.     register int i;
  92.     extern long rand();
  93.     
  94.     for(i = 0; i < TESTSIZE; i++)
  95.     testin[i]  = ((double)rand()) + (((double)rand()) / ((double)MAXRAND));
  96. }
  97.  
  98. #else
  99.  
  100. #define TESTSIZE 23
  101. double testin[TESTSIZE];
  102. static void init()
  103. {
  104.     register int i;
  105.     double v;
  106.     double inc = 0.1;
  107.     
  108.     for(v = -1.1, i = 0; i < TESTSIZE; v += inc, i++)
  109.     testin[i] = v;
  110. }
  111. #endif /* TEST1 */
  112.  
  113. #define ABS(x) (((x) < 0.0)? (-x) : (x))
  114. #define MARGIN 1.0e-6        /* 6 is arb */
  115.  
  116. #include <stdio.h>
  117. int main()
  118. {
  119.     double frac, integ, e, r;
  120.     register int i;
  121.     register int errors = 0;
  122.     extern double modf();
  123.  
  124.     init();
  125.     for(i = 0; i < TESTSIZE; i++)
  126.     {
  127.     frac = modf(testin[i], &integ);
  128.     if(frac >= 1.0)
  129.     {
  130.         printf("Error, frac >= 1, testin %f integ %f frac %f\n",
  131.            testin[i], integ, frac);
  132.         errors++;
  133.         continue;
  134.     }
  135.  
  136.     r = integ + frac;
  137.     e = testin[i] - r;
  138.     if(ABS(e) > MARGIN)
  139.     {
  140.         printf("In %f\tInt %f Frac %f Res %f\tError %f\n",
  141.            testin[i], integ, frac, r, e);
  142.         errors++;
  143.     }
  144. #ifdef TEST1
  145.     printf("%f\t%f  %f\n", testin[i], integ, frac);
  146. #endif
  147.     }
  148.     
  149.     printf("%d error(s)\n", errors);
  150.     return errors;
  151. }
  152. #endif /* TEST */
  153.