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_floor.c 1.3 95/01/18
26 */
27
28 #include "jerry-libm-internal.h"
29
30 /* floor(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 floor(x).
38 */
39
40 #define huge 1.0e300
41
42 double
floor(double x)43 floor (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 = i1 = 0;
60 }
61 else if (((i0 & 0x7fffffff) | i1) != 0)
62 {
63 i0 = 0xbff00000;
64 i1 = 0;
65 }
66 }
67 }
68 else
69 {
70 i = (0x000fffff) >> j0;
71 if (((i0 & i) | i1) == 0) /* x is integral */
72 {
73 return x;
74 }
75 if (huge + x > 0.0) /* raise inexact flag */
76 {
77 if (i0 < 0)
78 {
79 i0 += (0x00100000) >> j0;
80 }
81 i0 &= (~i);
82 i1 = 0;
83 }
84 }
85 }
86 else if (j0 > 51)
87 {
88 if (j0 == 0x400) /* inf or NaN */
89 {
90 return x + x;
91 }
92 else /* x is integral */
93 {
94 return x;
95 }
96 }
97 else
98 {
99 i = ((unsigned) (0xffffffff)) >> (j0 - 20);
100 if ((i1 & i) == 0) /* x is integral */
101 {
102 return x;
103 }
104 if (huge + x > 0.0) /* raise inexact flag */
105 {
106 if (i0 < 0)
107 {
108 if (j0 == 20)
109 {
110 i0 += 1;
111 }
112 else
113 {
114 j = i1 + (1 << (52 - j0));
115 if (j < i1) /* got a carry */
116 {
117 i0 += 1;
118 }
119 i1 = j;
120 }
121 }
122 i1 &= (~i);
123 }
124 }
125
126 double_accessor ret;
127 ret.as_int.hi = i0;
128 ret.as_int.lo = i1;
129 return ret.dbl;
130 } /* floor */
131
132 #undef huge
133