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 42double 43floor (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