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