1 
2 /* @(#)s_ceil.c 5.1 93/09/24 */
3 /*
4  * ====================================================
5  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6  *
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  * ====================================================
12  */
13 
14 /*
15  * ceil(x)
16  * Return x rounded toward -inf to integral value
17  * Method:
18  *	Bit twiddling.
19  * Exception:
20  *	Inexact flag raised if x not equal to ceil(x).
21  */
22 
23 #include "fdlibm.h"
24 
25 #ifdef _NEED_FLOAT64
26 
27 __float64
ceil64(__float64 x)28 ceil64(__float64 x)
29 {
30     __int32_t i0, i1, j0, j;
31     __uint32_t i;
32     EXTRACT_WORDS(i0, i1, x);
33     j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
34     if (j0 < 20) {
35         if (j0 < 0) {
36             if (i0 < 0) {
37                 i0 = 0x80000000;
38                 i1 = 0;
39             } else if ((i0 | i1) != 0) {
40                 i0 = 0x3ff00000;
41                 i1 = 0;
42             }
43         } else {
44             i = (0x000fffff) >> j0;
45             if (((i0 & i) | i1) == 0)
46                 return x; /* x is integral */
47             if (i0 > 0)
48                 i0 += (0x00100000) >> j0;
49             i0 &= (~i);
50             i1 = 0;
51         }
52     } else if (j0 > 51) {
53         if (j0 == 0x400)
54             return x + x; /* inf or NaN */
55         else
56             return x; /* x is integral */
57     } else {
58         i = ((__uint32_t)(0xffffffffUL)) >> (j0 - 20);
59         if ((i1 & i) == 0)
60             return x; /* x is integral */
61         if (i0 > 0) {
62             if (j0 == 20)
63                 i0 += 1;
64             else {
65                 j = i1 + ((__uint32_t) 1 << (52 - j0));
66                 if ((__uint32_t) j < (__uint32_t) i1)
67                     i0 += 1; /* got a carry */
68                 i1 = j;
69             }
70         }
71         i1 &= (~i);
72     }
73     INSERT_WORDS(x, i0, i1);
74     return x;
75 }
76 
77 _MATH_ALIAS_d_d(ceil)
78 
79 #endif /* _NEED_FLOAT64 */
80