Subversion Repositories Kolibri OS

Rev

Rev 1906 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. /* @(#)s_modf.c 5.1 93/09/24 */
  3. /*
  4.  * ====================================================
  5.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  6.  *
  7.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software is freely granted, provided that this notice
  10.  * is preserved.
  11.  * ====================================================
  12.  */
  13.  
  14. /*
  15. FUNCTION
  16.        <<modf>>, <<modff>>---split fractional and integer parts
  17.  
  18. INDEX
  19.         modf
  20. INDEX
  21.         modff
  22.  
  23. ANSI_SYNOPSIS
  24.         #include <math.h>
  25.         double modf(double <[val]>, double *<[ipart]>);
  26.         float modff(float <[val]>, float *<[ipart]>);
  27.  
  28. TRAD_SYNOPSIS
  29.         #include <math.h>
  30.         double modf(<[val]>, <[ipart]>)
  31.         double <[val]>;
  32.         double *<[ipart]>;
  33.  
  34.         float modff(<[val]>, <[ipart]>)
  35.         float <[val]>;
  36.         float *<[ipart]>;
  37.  
  38. DESCRIPTION
  39.         <<modf>> splits the double <[val]> apart into an integer part
  40.         and a fractional part, returning the fractional part and
  41.         storing the integer part in <<*<[ipart]>>>.  No rounding
  42.         whatsoever is done; the sum of the integer and fractional
  43.         parts is guaranteed to be exactly  equal to <[val]>.   That
  44.         is, if <[realpart]> = modf(<[val]>, &<[intpart]>); then
  45.         `<<<[realpart]>+<[intpart]>>>' is the same as <[val]>.
  46.         <<modff>> is identical, save that it takes and returns
  47.         <<float>> rather than <<double>> values.
  48.  
  49. RETURNS
  50.         The fractional part is returned.  Each result has the same
  51.         sign as the supplied argument <[val]>.
  52.  
  53. PORTABILITY
  54.         <<modf>> is ANSI C. <<modff>> is an extension.
  55.  
  56. QUICKREF
  57.         modf  ansi pure
  58.         modff - pure
  59.  
  60. */
  61.  
  62. /*
  63.  * modf(double x, double *iptr)
  64.  * return fraction part of x, and return x's integral part in *iptr.
  65.  * Method:
  66.  *      Bit twiddling.
  67.  *
  68.  * Exception:
  69.  *      No exception.
  70.  */
  71.  
  72. #include "fdlibm.h"
  73.  
  74. #ifndef _DOUBLE_IS_32BITS
  75.  
  76. #ifdef __STDC__
  77. static const double one = 1.0;
  78. #else
  79. static double one = 1.0;
  80. #endif
  81.  
  82. #ifdef __STDC__
  83.         double modf(double x, double *iptr)
  84. #else
  85.         double modf(x, iptr)
  86.         double x,*iptr;
  87. #endif
  88. {
  89.         __int32_t i0,i1,j0;
  90.         __uint32_t i;
  91.         EXTRACT_WORDS(i0,i1,x);
  92.         j0 = ((i0>>20)&0x7ff)-0x3ff;    /* exponent of x */
  93.         if(j0<20) {                     /* integer part in high x */
  94.             if(j0<0) {                  /* |x|<1 */
  95.                 INSERT_WORDS(*iptr,i0&0x80000000,0);    /* *iptr = +-0 */
  96.                 return x;
  97.             } else {
  98.                 i = (0x000fffff)>>j0;
  99.                 if(((i0&i)|i1)==0) {            /* x is integral */
  100.                     __uint32_t high;
  101.                     *iptr = x;
  102.                     GET_HIGH_WORD(high,x);
  103.                     INSERT_WORDS(x,high&0x80000000,0);  /* return +-0 */
  104.                     return x;
  105.                 } else {
  106.                     INSERT_WORDS(*iptr,i0&(~i),0);
  107.                     return x - *iptr;
  108.                 }
  109.             }
  110.         } else if (j0>51) {             /* no fraction part */
  111.             __uint32_t high;
  112.             *iptr = x*one;
  113.             GET_HIGH_WORD(high,x);
  114.             INSERT_WORDS(x,high&0x80000000,0);  /* return +-0 */
  115.             return x;
  116.         } else {                        /* fraction part in low x */
  117.             i = ((__uint32_t)(0xffffffff))>>(j0-20);
  118.             if((i1&i)==0) {             /* x is integral */
  119.                 __uint32_t high;
  120.                 *iptr = x;
  121.                 GET_HIGH_WORD(high,x);
  122.                 INSERT_WORDS(x,high&0x80000000,0);      /* return +-0 */
  123.                 return x;
  124.             } else {
  125.                 INSERT_WORDS(*iptr,i0,i1&(~i));
  126.                 return x - *iptr;
  127.             }
  128.         }
  129. }
  130.  
  131. #endif /* _DOUBLE_IS_32BITS */
  132.