Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libm / common / s_modf.c
blobe552a9460ef9a621c558d7064c3bc8b91cfd1af5
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 SYNOPSIS
24 #include <math.h>
25 double modf(double <[val]>, double *<[ipart]>);
26 float modff(float <[val]>, float *<[ipart]>);
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.
39 RETURNS
40 The fractional part is returned. Each result has the same
41 sign as the supplied argument <[val]>.
43 PORTABILITY
44 <<modf>> is ANSI C. <<modff>> is an extension.
46 QUICKREF
47 modf ansi pure
48 modff - pure
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.
58 * Exception:
59 * No exception.
62 #include "fdlibm.h"
64 #ifndef _DOUBLE_IS_32BITS
66 #ifdef __STDC__
67 double modf(double x, double *iptr)
68 #else
69 double modf(x, iptr)
70 double x,*iptr;
71 #endif
73 __int32_t i0,i1,j0;
74 __uint32_t i;
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 */
80 return x;
81 } else {
82 i = (0x000fffff)>>j0;
83 if(((i0&i)|i1)==0) { /* x is integral */
84 *iptr = x;
85 INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
86 return x;
87 } else {
88 INSERT_WORDS(*iptr,i0&(~i),0);
89 return x - *iptr;
92 } else if (j0>51) { /* no fraction part */
93 *iptr = x;
94 if (__fpclassifyd(x) == FP_NAN) return *iptr = x+x; /* x is NaN, return NaN */
95 INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
96 return x;
97 } else { /* fraction part in low x */
98 i = ((__uint32_t)(0xffffffff))>>(j0-20);
99 if((i1&i)==0) { /* x is integral */
100 *iptr = x;
101 INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
102 return x;
103 } else {
104 INSERT_WORDS(*iptr,i0,i1&(~i));
105 return x - *iptr;
110 #endif /* _DOUBLE_IS_32BITS */