home *** CD-ROM | disk | FTP | other *** search
/ Serving the Web / ServingTheWeb1995.disc1of1.iso / linux / slacksrce / d / libc / libc-4.6 / libc-4 / libc-linux / cvt / cvt.c next >
Encoding:
C/C++ Source or Header  |  1993-02-21  |  2.0 KB  |  128 lines

  1. #include <stdlib.h>
  2. #include <math.h>
  3. #include <ieee754.h>
  4.  
  5. #define    IEEE    1
  6.  
  7. /*
  8.  *    ecvt converts to decimal
  9.  *    the number of digits is specified by ndigit
  10.  *    decpt is set to the position of the decimal point
  11.  *    sign is set to 0 for positive, 1 for negative
  12.  */
  13.  
  14. #ifdef IEEE
  15.  
  16. static inline int
  17. __isspecial(double f, char *bp)
  18. {
  19.     union ieee754_double *ip = (union ieee754_double *) &f;
  20.  
  21.     if ((ip->ieee.exponent & 0x7ff) != 0x7ff)
  22.         return(0);
  23.     if (ip->ieee.mantissa0 || ip->ieee.mantissa1)
  24.         strcpy(bp, "NaN");
  25.     else if (ip->ieee.negative)
  26.         strcpy(bp, "-Infinity");
  27.     else
  28.         strcpy(bp, "Infinity");
  29.     return(1);
  30. }
  31.  
  32. #define    NDIG    512
  33. #else
  34. #define    NDIG    80
  35. #endif
  36.  
  37. static char*
  38. cvt(double arg, size_t ndigits, int *decpt, int *sign, int eflag)
  39. {
  40.     register int r2;
  41.     double fi, fj;
  42.     register char *p, *p1;
  43.     static char buf[NDIG];
  44.  
  45. #ifdef IEEE
  46.     /* XXX */
  47.     if (__isspecial(arg, buf))
  48.         return(buf);
  49. #endif
  50.     if (ndigits>=NDIG-1)
  51.         ndigits = NDIG-2;
  52.     r2 = 0;
  53.     *sign = 0;
  54.     p = &buf[0];
  55.     if (arg<0) {
  56.         *sign = 1;
  57.         arg = -arg;
  58.     }
  59.     arg = modf(arg, &fi);
  60.     p1 = &buf[NDIG];
  61.     /*
  62.      * Do integer part
  63.      */
  64.     if (fi != 0) {
  65.         p1 = &buf[NDIG];
  66.         while (fi != 0) {
  67.             fj = modf(fi/10, &fi);
  68.             *--p1 = (int)((fj+.03)*10) + '0';
  69.             r2++;
  70.         }
  71.         while (p1 < &buf[NDIG])
  72.             *p++ = *p1++;
  73.     } else if (arg > 0) {
  74.         while ((fj = arg*10) < 1) {
  75.             arg = fj;
  76.             r2--;
  77.         }
  78.     }
  79.     p1 = &buf[ndigits];
  80.     if (eflag==0)
  81.         p1 += r2;
  82.     *decpt = r2;
  83.     if (p1 < &buf[0]) {
  84.         buf[0] = '\0';
  85.         return(buf);
  86.     }
  87.     while (p<=p1 && p<&buf[NDIG]) {
  88.         arg *= 10;
  89.         arg = modf(arg, &fj);
  90.         *p++ = (int)fj + '0';
  91.     }
  92.     if (p1 >= &buf[NDIG]) {
  93.         buf[NDIG-1] = '\0';
  94.         return(buf);
  95.     }
  96.     p = p1;
  97.     *p1 += 5;
  98.     while (*p1 > '9') {
  99.         *p1 = '0';
  100.         if (p1>buf)
  101.             ++*--p1;
  102.         else {
  103.             *p1 = '1';
  104.             (*decpt)++;
  105.             if (eflag==0) {
  106.                 if (p>buf)
  107.                     *p = '0';
  108.                 p++;
  109.             }
  110.         }
  111.     }
  112.     *p = '\0';
  113.     return(buf);
  114. }
  115.  
  116. char*
  117. ecvt(double arg, size_t ndigits, int *decpt, int *sign)
  118. {
  119.     return(cvt(arg, ndigits, decpt, sign, 1));
  120. }
  121.  
  122. char*
  123. fcvt(double arg, size_t ndigits, int *decpt, int *sign)
  124. {
  125.     return(cvt(arg, ndigits, decpt, sign, 0));
  126. }
  127.  
  128.