fixed more binutils issues (newer gcc/libc)
[zpugcc/jano.git] / toolchain / gcc / newlib / libm / common / s_modf.c
blob01151397d64d00e817b897f1a29e2f359d1e79b4
2 /* @(#)s_modf.c 5.1 93/09/24 */
3 /*
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
10 * is preserved.
11 * ====================================================
15 FUNCTION
16 <<modf>>, <<modff>>---split fractional and integer parts
18 INDEX
19 modf
20 INDEX
21 modff
23 ANSI_SYNOPSIS
24 #include <math.h>
25 double modf(double <[val]>, double *<[ipart]>);
26 float modff(float <[val]>, float *<[ipart]>);
28 TRAD_SYNOPSIS
29 #include <math.h>
30 double modf(<[val]>, <[ipart]>)
31 double <[val]>;
32 double *<[ipart]>;
34 float modff(<[val]>, <[ipart]>)
35 float <[val]>;
36 float *<[ipart]>;
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.
49 RETURNS
50 The fractional part is returned. Each result has the same
51 sign as the supplied argument <[val]>.
53 PORTABILITY
54 <<modf>> is ANSI C. <<modff>> is an extension.
56 QUICKREF
57 modf ansi pure
58 modff - pure
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.
68 * Exception:
69 * No exception.
72 #include "fdlibm.h"
74 #ifndef _DOUBLE_IS_32BITS
76 #ifdef __STDC__
77 static const double one = 1.0;
78 #else
79 static double one = 1.0;
80 #endif
82 #ifdef __STDC__
83 double modf(double x, double *iptr)
84 #else
85 double modf(x, iptr)
86 double x,*iptr;
87 #endif
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;
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;
131 #endif /* _DOUBLE_IS_32BITS */