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 * @(#)e_log10.c 1.3 95/01/18 26425bb815Sopenharmony_ci */ 27425bb815Sopenharmony_ci 28425bb815Sopenharmony_ci#include "jerry-libm-internal.h" 29425bb815Sopenharmony_ci 30425bb815Sopenharmony_ci/* log10(x) 31425bb815Sopenharmony_ci * Return the base 10 logarithm of x 32425bb815Sopenharmony_ci * 33425bb815Sopenharmony_ci * Method : 34425bb815Sopenharmony_ci * Let log10_2hi = leading 40 bits of log10(2) and 35425bb815Sopenharmony_ci * log10_2lo = log10(2) - log10_2hi, 36425bb815Sopenharmony_ci * ivln10 = 1/log(10) rounded. 37425bb815Sopenharmony_ci * Then 38425bb815Sopenharmony_ci * n = ilogb(x), 39425bb815Sopenharmony_ci * if(n<0) n = n+1; 40425bb815Sopenharmony_ci * x = scalbn(x,-n); 41425bb815Sopenharmony_ci * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x)) 42425bb815Sopenharmony_ci * 43425bb815Sopenharmony_ci * Note 1: 44425bb815Sopenharmony_ci * To guarantee log10(10**n)=n, where 10**n is normal, the rounding 45425bb815Sopenharmony_ci * mode must set to Round-to-Nearest. 46425bb815Sopenharmony_ci * Note 2: 47425bb815Sopenharmony_ci * [1/log(10)] rounded to 53 bits has error .198 ulps; 48425bb815Sopenharmony_ci * log10 is monotonic at all binary break points. 49425bb815Sopenharmony_ci * 50425bb815Sopenharmony_ci * Special cases: 51425bb815Sopenharmony_ci * log10(x) is NaN with signal if x < 0; 52425bb815Sopenharmony_ci * log10(+INF) is +INF with no signal; log10(0) is -INF with signal; 53425bb815Sopenharmony_ci * log10(NaN) is that NaN with no signal; 54425bb815Sopenharmony_ci * log10(10**N) = N for N=0,1,...,22. 55425bb815Sopenharmony_ci * 56425bb815Sopenharmony_ci * Constants: 57425bb815Sopenharmony_ci * The hexadecimal values are the intended ones for the following constants. 58425bb815Sopenharmony_ci * The decimal values may be used, provided that the compiler will convert 59425bb815Sopenharmony_ci * from decimal to binary accurately enough to produce the hexadecimal values 60425bb815Sopenharmony_ci * shown. 61425bb815Sopenharmony_ci */ 62425bb815Sopenharmony_ci 63425bb815Sopenharmony_ci#define zero 0.0 64425bb815Sopenharmony_ci#define two54 1.80143985094819840000e+16 /* 0x43500000, 0x00000000 */ 65425bb815Sopenharmony_ci#define ivln10 4.34294481903251816668e-01 /* 0x3FDBCB7B, 0x1526E50E */ 66425bb815Sopenharmony_ci#define log10_2hi 3.01029995663611771306e-01 /* 0x3FD34413, 0x509F6000 */ 67425bb815Sopenharmony_ci#define log10_2lo 3.69423907715893078616e-13 /* 0x3D59FEF3, 0x11F12B36 */ 68425bb815Sopenharmony_ci 69425bb815Sopenharmony_cidouble 70425bb815Sopenharmony_cilog10 (double x) 71425bb815Sopenharmony_ci{ 72425bb815Sopenharmony_ci double y, z; 73425bb815Sopenharmony_ci int i, k, hx; 74425bb815Sopenharmony_ci unsigned lx; 75425bb815Sopenharmony_ci double_accessor temp; 76425bb815Sopenharmony_ci 77425bb815Sopenharmony_ci hx = __HI (x); /* high word of x */ 78425bb815Sopenharmony_ci lx = __LO (x); /* low word of x */ 79425bb815Sopenharmony_ci 80425bb815Sopenharmony_ci k = 0; 81425bb815Sopenharmony_ci if (hx < 0x00100000) 82425bb815Sopenharmony_ci { 83425bb815Sopenharmony_ci /* x < 2**-1022 */ 84425bb815Sopenharmony_ci if (((hx & 0x7fffffff) | lx) == 0) 85425bb815Sopenharmony_ci { 86425bb815Sopenharmony_ci /* log(+-0)=-inf */ 87425bb815Sopenharmony_ci return -two54 / zero; 88425bb815Sopenharmony_ci } 89425bb815Sopenharmony_ci if (hx < 0) 90425bb815Sopenharmony_ci { 91425bb815Sopenharmony_ci /* log(-#) = NaN */ 92425bb815Sopenharmony_ci return (x - x) / zero; 93425bb815Sopenharmony_ci } 94425bb815Sopenharmony_ci k -= 54; 95425bb815Sopenharmony_ci x *= two54; /* subnormal number, scale up x */ 96425bb815Sopenharmony_ci hx = __HI (x); /* high word of x */ 97425bb815Sopenharmony_ci } 98425bb815Sopenharmony_ci if (hx >= 0x7ff00000) 99425bb815Sopenharmony_ci { 100425bb815Sopenharmony_ci return x + x; 101425bb815Sopenharmony_ci } 102425bb815Sopenharmony_ci k += (hx >> 20) - 1023; 103425bb815Sopenharmony_ci i = ((unsigned) k & 0x80000000) >> 31; 104425bb815Sopenharmony_ci hx = (hx & 0x000fffff) | ((0x3ff - i) << 20); 105425bb815Sopenharmony_ci y = (double) (k + i); 106425bb815Sopenharmony_ci temp.dbl = x; 107425bb815Sopenharmony_ci temp.as_int.hi = hx; 108425bb815Sopenharmony_ci z = y * log10_2lo + ivln10 * log (temp.dbl); 109425bb815Sopenharmony_ci return z + y * log10_2hi; 110425bb815Sopenharmony_ci} /* log10 */ 111425bb815Sopenharmony_ci 112425bb815Sopenharmony_ci#undef zero 113425bb815Sopenharmony_ci#undef two54 114425bb815Sopenharmony_ci#undef ivln10 115425bb815Sopenharmony_ci#undef log10_2hi 116425bb815Sopenharmony_ci#undef log10_2lo 117