1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci * 15425bb815Sopenharmony_ci * This file is based on work under the following copyright and permission 16425bb815Sopenharmony_ci * notice: 17425bb815Sopenharmony_ci * 18425bb815Sopenharmony_ci * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 19425bb815Sopenharmony_ci * 20425bb815Sopenharmony_ci * Developed at SunSoft, a Sun Microsystems, Inc. business. 21425bb815Sopenharmony_ci * Permission to use, copy, modify, and distribute this 22425bb815Sopenharmony_ci * software is freely granted, provided that this notice 23425bb815Sopenharmony_ci * is preserved. 24425bb815Sopenharmony_ci * 25425bb815Sopenharmony_ci * @(#)s_floor.c 1.3 95/01/18 26425bb815Sopenharmony_ci */ 27425bb815Sopenharmony_ci 28425bb815Sopenharmony_ci#include "jerry-libm-internal.h" 29425bb815Sopenharmony_ci 30425bb815Sopenharmony_ci/* floor(x) 31425bb815Sopenharmony_ci * Return x rounded toward -inf to integral value 32425bb815Sopenharmony_ci * 33425bb815Sopenharmony_ci * Method: 34425bb815Sopenharmony_ci * Bit twiddling. 35425bb815Sopenharmony_ci * 36425bb815Sopenharmony_ci * Exception: 37425bb815Sopenharmony_ci * Inexact flag raised if x not equal to floor(x). 38425bb815Sopenharmony_ci */ 39425bb815Sopenharmony_ci 40425bb815Sopenharmony_ci#define huge 1.0e300 41425bb815Sopenharmony_ci 42425bb815Sopenharmony_cidouble 43425bb815Sopenharmony_cifloor (double x) 44425bb815Sopenharmony_ci{ 45425bb815Sopenharmony_ci int i0, i1, j0; 46425bb815Sopenharmony_ci unsigned i, j; 47425bb815Sopenharmony_ci 48425bb815Sopenharmony_ci i0 = __HI (x); 49425bb815Sopenharmony_ci i1 = __LO (x); 50425bb815Sopenharmony_ci j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; 51425bb815Sopenharmony_ci if (j0 < 20) 52425bb815Sopenharmony_ci { 53425bb815Sopenharmony_ci if (j0 < 0) /* raise inexact if x != 0 */ 54425bb815Sopenharmony_ci { 55425bb815Sopenharmony_ci if (huge + x > 0.0) /* return 0 * sign(x) if |x| < 1 */ 56425bb815Sopenharmony_ci { 57425bb815Sopenharmony_ci if (i0 >= 0) 58425bb815Sopenharmony_ci { 59425bb815Sopenharmony_ci i0 = i1 = 0; 60425bb815Sopenharmony_ci } 61425bb815Sopenharmony_ci else if (((i0 & 0x7fffffff) | i1) != 0) 62425bb815Sopenharmony_ci { 63425bb815Sopenharmony_ci i0 = 0xbff00000; 64425bb815Sopenharmony_ci i1 = 0; 65425bb815Sopenharmony_ci } 66425bb815Sopenharmony_ci } 67425bb815Sopenharmony_ci } 68425bb815Sopenharmony_ci else 69425bb815Sopenharmony_ci { 70425bb815Sopenharmony_ci i = (0x000fffff) >> j0; 71425bb815Sopenharmony_ci if (((i0 & i) | i1) == 0) /* x is integral */ 72425bb815Sopenharmony_ci { 73425bb815Sopenharmony_ci return x; 74425bb815Sopenharmony_ci } 75425bb815Sopenharmony_ci if (huge + x > 0.0) /* raise inexact flag */ 76425bb815Sopenharmony_ci { 77425bb815Sopenharmony_ci if (i0 < 0) 78425bb815Sopenharmony_ci { 79425bb815Sopenharmony_ci i0 += (0x00100000) >> j0; 80425bb815Sopenharmony_ci } 81425bb815Sopenharmony_ci i0 &= (~i); 82425bb815Sopenharmony_ci i1 = 0; 83425bb815Sopenharmony_ci } 84425bb815Sopenharmony_ci } 85425bb815Sopenharmony_ci } 86425bb815Sopenharmony_ci else if (j0 > 51) 87425bb815Sopenharmony_ci { 88425bb815Sopenharmony_ci if (j0 == 0x400) /* inf or NaN */ 89425bb815Sopenharmony_ci { 90425bb815Sopenharmony_ci return x + x; 91425bb815Sopenharmony_ci } 92425bb815Sopenharmony_ci else /* x is integral */ 93425bb815Sopenharmony_ci { 94425bb815Sopenharmony_ci return x; 95425bb815Sopenharmony_ci } 96425bb815Sopenharmony_ci } 97425bb815Sopenharmony_ci else 98425bb815Sopenharmony_ci { 99425bb815Sopenharmony_ci i = ((unsigned) (0xffffffff)) >> (j0 - 20); 100425bb815Sopenharmony_ci if ((i1 & i) == 0) /* x is integral */ 101425bb815Sopenharmony_ci { 102425bb815Sopenharmony_ci return x; 103425bb815Sopenharmony_ci } 104425bb815Sopenharmony_ci if (huge + x > 0.0) /* raise inexact flag */ 105425bb815Sopenharmony_ci { 106425bb815Sopenharmony_ci if (i0 < 0) 107425bb815Sopenharmony_ci { 108425bb815Sopenharmony_ci if (j0 == 20) 109425bb815Sopenharmony_ci { 110425bb815Sopenharmony_ci i0 += 1; 111425bb815Sopenharmony_ci } 112425bb815Sopenharmony_ci else 113425bb815Sopenharmony_ci { 114425bb815Sopenharmony_ci j = i1 + (1 << (52 - j0)); 115425bb815Sopenharmony_ci if (j < i1) /* got a carry */ 116425bb815Sopenharmony_ci { 117425bb815Sopenharmony_ci i0 += 1; 118425bb815Sopenharmony_ci } 119425bb815Sopenharmony_ci i1 = j; 120425bb815Sopenharmony_ci } 121425bb815Sopenharmony_ci } 122425bb815Sopenharmony_ci i1 &= (~i); 123425bb815Sopenharmony_ci } 124425bb815Sopenharmony_ci } 125425bb815Sopenharmony_ci 126425bb815Sopenharmony_ci double_accessor ret; 127425bb815Sopenharmony_ci ret.as_int.hi = i0; 128425bb815Sopenharmony_ci ret.as_int.lo = i1; 129425bb815Sopenharmony_ci return ret.dbl; 130425bb815Sopenharmony_ci} /* floor */ 131425bb815Sopenharmony_ci 132425bb815Sopenharmony_ci#undef huge 133