initial cmath code and minor libm.h update
[libm] / src / math / truncf.c
1 /* origin: FreeBSD /usr/src/lib/msun/src/s_truncf.c */
2 /*
3  * ====================================================
4  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5  *
6  * Developed at SunPro, a Sun Microsystems, Inc. business.
7  * Permission to use, copy, modify, and distribute this
8  * software is freely granted, provided that this notice
9  * is preserved.
10  * ====================================================
11  */
12 /*
13  * truncf(x)
14  * Return x rounded toward 0 to integral value
15  * Method:
16  *      Bit twiddling.
17  * Exception:
18  *      Inexact flag raised if x not equal to truncf(x).
19  */
20
21 #include "libm.h"
22
23 static const float huge = 1.0e30F;
24
25 float truncf(float x)
26 {
27         int32_t i0,j0;
28         uint32_t i;
29
30         GET_FLOAT_WORD(i0, x);
31         j0 = ((i0>>23)&0xff) - 0x7f;
32         if (j0 < 23) {
33                 if (j0 < 0) {  /* |x|<1, return 0*sign(x) */
34                         /* raise inexact if x != 0 */
35                         if (huge+x > 0.0F)
36                                 i0 &= 0x80000000;
37                 } else {
38                         i = 0x007fffff>>j0;
39                         if ((i0&i) == 0)
40                                 return x; /* x is integral */
41                         /* raise inexact */
42                         if (huge+x > 0.0F)
43                                 i0 &= ~i;
44                 }
45         } else {
46                 if (j0 == 0x80)
47                         return x + x;  /* inf or NaN */
48                 return x;              /* x is integral */
49         }
50         SET_FLOAT_WORD(x, i0);
51         return x;
52 }