2 /* @(#)s_modf.c 5.1 93/09/24 */
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
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
11 * ====================================================
16 <<modf>>, <<modff>>---split fractional and integer parts
25 double modf(double <[val]>, double *<[ipart]>);
26 float modff(float <[val]>, float *<[ipart]>);
29 <<modf>> splits the double <[val]> apart into an integer part
30 and a fractional part, returning the fractional part and
31 storing the integer part in <<*<[ipart]>>>. No rounding
32 whatsoever is done; the sum of the integer and fractional
33 parts is guaranteed to be exactly equal to <[val]>. That
34 is, if <[realpart]> = modf(<[val]>, &<[intpart]>); then
35 `<<<[realpart]>+<[intpart]>>>' is the same as <[val]>.
36 <<modff>> is identical, save that it takes and returns
37 <<float>> rather than <<double>> values.
40 The fractional part is returned. Each result has the same
41 sign as the supplied argument <[val]>.
44 <<modf>> is ANSI C. <<modff>> is an extension.
53 * modf(double x, double *iptr)
54 * return fraction part of x, and return x's integral part in *iptr.
64 #ifndef _DOUBLE_IS_32BITS
67 double modf(double x
, double *iptr
)
75 EXTRACT_WORDS(i0
,i1
,x
);
76 j0
= ((i0
>>20)&0x7ff)-0x3ff; /* exponent of x */
77 if(j0
<20) { /* integer part in high x */
78 if(j0
<0) { /* |x|<1 */
79 INSERT_WORDS(*iptr
,i0
&0x80000000,0); /* *iptr = +-0 */
83 if(((i0
&i
)|i1
)==0) { /* x is integral */
85 INSERT_WORDS(x
,i0
&0x80000000,0); /* return +-0 */
88 INSERT_WORDS(*iptr
,i0
&(~i
),0);
92 } else if (j0
>51) { /* no fraction part */
94 if (__fpclassifyd(x
) == FP_NAN
) return *iptr
= x
+x
; /* x is NaN, return NaN */
95 INSERT_WORDS(x
,i0
&0x80000000,0); /* return +-0 */
97 } else { /* fraction part in low x */
98 i
= ((__uint32_t
)(0xffffffff))>>(j0
-20);
99 if((i1
&i
)==0) { /* x is integral */
101 INSERT_WORDS(x
,i0
&0x80000000,0); /* return +-0 */
104 INSERT_WORDS(*iptr
,i0
,i1
&(~i
));
110 #endif /* _DOUBLE_IS_32BITS */