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 SYNOPSIS
24 #include <math.h>
25 double modf(double <[val]>, double *<[ipart]>);
26 float modff(float <[val]>, float *<[ipart]>);
27
28 DESCRIPTION
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.
38
39 RETURNS
40 The fractional part is returned. Each result has the same
41 sign as the supplied argument <[val]>.
42
43 PORTABILITY
44 <<modf>> is ANSI C. <<modff>> is an extension.
45
46 QUICKREF
47 modf ansi pure
48 modff - pure
49
50 */
51
52 /*
53 * modf(double x, double *iptr)
54 * return fraction part of x, and return x's integral part in *iptr.
55 * Method:
56 * Bit twiddling.
57 *
58 * Exception:
59 * No exception.
60 */
61
62 #include "fdlibm.h"
63
64 #ifdef _NEED_FLOAT64
65
66 __float64
modf64(__float64 x,__float64 * iptr)67 modf64(__float64 x, __float64 *iptr)
68 {
69 __int32_t i0,i1,j0;
70 __uint32_t i;
71 EXTRACT_WORDS(i0,i1,x);
72 j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
73 if(j0<20) { /* integer part in high x */
74 if(j0<0) { /* |x|<1 */
75 INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
76 return x;
77 } else {
78 i = (0x000fffff)>>j0;
79 if(((i0&i)|i1)==0) { /* x is integral */
80 *iptr = x;
81 INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
82 return x;
83 } else {
84 INSERT_WORDS(*iptr,i0&(~i),0);
85 return x - *iptr;
86 }
87 }
88 } else if (j0>51) { /* no fraction part */
89 *iptr = x;
90 if (__fpclassifyd(x) == FP_NAN) return *iptr = x+x; /* x is NaN, return NaN */
91 INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
92 return x;
93 } else { /* fraction part in low x */
94 i = ((__uint32_t)(0xffffffff))>>(j0-20);
95 if((i1&i)==0) { /* x is integral */
96 *iptr = x;
97 INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
98 return x;
99 } else {
100 INSERT_WORDS(*iptr,i0,i1&(~i));
101 return x - *iptr;
102 }
103 }
104 }
105
106 _MATH_ALIAS_d_dD(modf)
107
108 #endif /* _NEED_FLOAT64 */
109