1 /* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * This file is based on work under the following copyright and permission
16 * notice:
17 *
18 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
19 *
20 * Developed at SunSoft, a Sun Microsystems, Inc. business.
21 * Permission to use, copy, modify, and distribute this
22 * software is freely granted, provided that this notice
23 * is preserved.
24 *
25 * @(#)s_ceil.c 1.3 95/01/18
26 */
27
28 #include "jerry-libm-internal.h"
29
30 /* ceil(x)
31 * Return x rounded toward -inf to integral value
32 *
33 * Method:
34 * Bit twiddling.
35 *
36 * Exception:
37 * Inexact flag raised if x not equal to ceil(x).
38 */
39
40 #define huge 1.0e300
41
42 double
ceil(double x)43 ceil (double x)
44 {
45 int i0, i1, j0;
46 unsigned i, j;
47
48 i0 = __HI (x);
49 i1 = __LO (x);
50 j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
51 if (j0 < 20)
52 {
53 if (j0 < 0) /* raise inexact if x != 0 */
54 {
55 if (huge + x > 0.0) /* return 0 * sign(x) if |x| < 1 */
56 {
57 if (i0 < 0)
58 {
59 i0 = 0x80000000;
60 i1 = 0;
61 }
62 else if ((i0 | i1) != 0)
63 {
64 i0 = 0x3ff00000;
65 i1 = 0;
66 }
67 }
68 }
69 else
70 {
71 i = (0x000fffff) >> j0;
72 if (((i0 & i) | i1) == 0) /* x is integral */
73 {
74 return x;
75 }
76 if (huge + x > 0.0) /* raise inexact flag */
77 {
78 if (i0 > 0)
79 {
80 i0 += (0x00100000) >> j0;
81 }
82 i0 &= (~i);
83 i1 = 0;
84 }
85 }
86 }
87 else if (j0 > 51)
88 {
89 if (j0 == 0x400) /* inf or NaN */
90 {
91 return x + x;
92 }
93 else /* x is integral */
94 {
95 return x;
96 }
97 }
98 else
99 {
100 i = ((unsigned) (0xffffffff)) >> (j0 - 20);
101 if ((i1 & i) == 0) /* x is integral */
102 {
103 return x;
104 }
105 if (huge + x > 0.0) /* raise inexact flag */
106 {
107 if (i0 > 0)
108 {
109 if (j0 == 20)
110 {
111 i0 += 1;
112 }
113 else
114 {
115 j = i1 + (1 << (52 - j0));
116 if (j < i1) /* got a carry */
117 {
118 i0 += 1;
119 }
120 i1 = j;
121 }
122 }
123 i1 &= (~i);
124 }
125 }
126
127 double_accessor ret;
128 ret.as_int.hi = i0;
129 ret.as_int.lo = i1;
130 return ret.dbl;
131 } /* ceil */
132
133 #undef huge
134