TODO update
[libm] / src / math / modff.c
1 /* origin: FreeBSD /usr/src/lib/msun/src/s_modff.c */
2 /*
3  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4  */
5 /*
6  * ====================================================
7  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8  *
9  * Developed at SunPro, a Sun Microsystems, Inc. business.
10  * Permission to use, copy, modify, and distribute this
11  * software is freely granted, provided that this notice
12  * is preserved.
13  * ====================================================
14  */
15
16 #include "libm.h"
17
18 static const float one = 1.0;
19
20 float modff(float x, float *iptr)
21 {
22         int32_t i0,j0;
23         uint32_t i;
24
25         GET_FLOAT_WORD(i0, x);
26         j0 = ((i0>>23) & 0xff) - 0x7f;  /* exponent of x */
27         if (j0 < 23) {  /* integer part in x */
28                 if (j0 < 0) {  /* |x| < 1 */
29                         SET_FLOAT_WORD(*iptr, i0 & 0x80000000);  /* *iptr = +-0 */
30                         return x;
31                 }
32                 i = 0x007fffff >> j0;
33                 if ((i0&i) == 0) {  /* x is integral */
34                         uint32_t ix;
35                         *iptr = x;
36                         GET_FLOAT_WORD(ix, x);
37                         SET_FLOAT_WORD(x, ix & 0x80000000);  /* return +-0 */
38                         return x;
39                 }
40                 SET_FLOAT_WORD(*iptr, i0&~i);
41                 return x - *iptr;
42         } else {        /* no fraction part */
43                 uint32_t ix;
44                 *iptr = x*one;
45                 if (x != x)  /* NaN */
46                         return x;
47                 GET_FLOAT_WORD(ix, x);
48                 SET_FLOAT_WORD(x, ix & 0x80000000);  /* return +-0 */
49                 return x;
50         }
51 }