• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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