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]>);
30 double modf(<[val]>, <[ipart]>)
34 float modff(<[val]>, <[ipart]>)
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.
50 The fractional part is returned. Each result has the same
51 sign as the supplied argument <[val]>.
54 <<modf>> is ANSI C. <<modff>> is an extension.
63 * modf(double x, double *iptr)
64 * return fraction part of x, and return x's integral part in *iptr.
74 #ifndef _DOUBLE_IS_32BITS
77 static const double one
= 1.0;
79 static double one
= 1.0;
83 double modf(double x
, double *iptr
)
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 */
99 if(((i0
&i
)|i1
)==0) { /* x is integral */
102 GET_HIGH_WORD(high
,x
);
103 INSERT_WORDS(x
,high
&0x80000000,0); /* return +-0 */
106 INSERT_WORDS(*iptr
,i0
&(~i
),0);
110 } else if (j0
>51) { /* no fraction part */
113 GET_HIGH_WORD(high
,x
);
114 INSERT_WORDS(x
,high
&0x80000000,0); /* return +-0 */
116 } else { /* fraction part in low x */
117 i
= ((__uint32_t
)(0xffffffff))>>(j0
-20);
118 if((i1
&i
)==0) { /* x is integral */
121 GET_HIGH_WORD(high
,x
);
122 INSERT_WORDS(x
,high
&0x80000000,0); /* return +-0 */
125 INSERT_WORDS(*iptr
,i0
,i1
&(~i
));
131 #endif /* _DOUBLE_IS_32BITS */