TODO update
[libm] / src / math / ceilf.c
1 /* origin: FreeBSD /usr/src/lib/msun/src/s_ceilf.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 huge = 1.0e30;
19
20 float ceilf(float x)
21 {
22         int32_t i0,j0;
23         uint32_t i;
24
25         GET_FLOAT_WORD(i0, x);
26         j0 = ((i0>>23)&0xff) - 0x7f;
27         if (j0 < 23) {
28                 if (j0 < 0) {
29                         /* raise inexact if x != 0 */
30                         if (huge+x > (float)0.0) {
31                                 /* return 0*sign(x) if |x|<1 */
32                                 if (i0 < 0)
33                                         i0 = 0x80000000;
34                                 else if(i0 != 0)
35                                         i0 = 0x3f800000;
36                         }
37                 } else {
38                         i = 0x007fffff>>j0;
39                         if ((i0&i) == 0)
40                                 return x; /* x is integral */
41                         /* raise inexact flag */
42                         if (huge+x > (float)0.0) {
43                                 if (i0 > 0)
44                                         i0 += 0x00800000>>j0;
45                                 i0 &= ~i;
46                         }
47                 }
48         } else {
49                 if (j0 == 0x80)  /* inf or NaN */
50                         return x+x;
51                 return x; /* x is integral */
52         }
53         SET_FLOAT_WORD(x, i0);
54         return x;
55 }