From 58ef3f64f4ce7232138a47ec3315a3d484960e0c Mon Sep 17 00:00:00 2001 From: GUNJ JOSHI Date: Tue, 16 Apr 2024 11:53:23 +0530 Subject: [PATCH 1/3] refactor: update math/base/special/log10 to freeBSD v12.2.0 --- .../math/base/special/log10/lib/klog.js | 102 ------------------ .../math/base/special/log10/lib/main.js | 80 ++++++++++---- .../math/base/special/log10/lib/polyval_p.js | 47 -------- .../math/base/special/log10/lib/polyval_q.js | 47 -------- .../math/base/special/log10/package.json | 1 - .../base/special/log10/scripts/evalpoly.js | 81 -------------- .../math/base/special/log10/test/test.js | 7 ++ .../math/base/special/log10/test/test.klog.js | 50 --------- 8 files changed, 67 insertions(+), 348 deletions(-) delete mode 100644 lib/node_modules/@stdlib/math/base/special/log10/lib/klog.js delete mode 100644 lib/node_modules/@stdlib/math/base/special/log10/lib/polyval_p.js delete mode 100644 lib/node_modules/@stdlib/math/base/special/log10/lib/polyval_q.js delete mode 100644 lib/node_modules/@stdlib/math/base/special/log10/scripts/evalpoly.js delete mode 100644 lib/node_modules/@stdlib/math/base/special/log10/test/test.klog.js diff --git a/lib/node_modules/@stdlib/math/base/special/log10/lib/klog.js b/lib/node_modules/@stdlib/math/base/special/log10/lib/klog.js deleted file mode 100644 index 0fce3ed6b85..00000000000 --- a/lib/node_modules/@stdlib/math/base/special/log10/lib/klog.js +++ /dev/null @@ -1,102 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2018 The Stdlib Authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -* -* ## Notice -* -* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/9.3.0/lib/msun/src/k_log.h}. The implementation follows the original, but has been modified for JavaScript. -* -* ```text -* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. -* -* Developed at SunPro, a Sun Microsystems, Inc. business. -* Permission to use, copy, modify, and distribute this -* software is freely granted, provided that this notice -* is preserved. -* ``` -*/ - -'use strict'; - -// MODULES // - -var getHighWord = require( '@stdlib/number/float64/base/get-high-word' ); -var polyvalP = require( './polyval_p.js' ); -var polyvalQ = require( './polyval_q.js' ); - - -// VARIABLES // - -// 0x000fffff = 1048575 => 0 00000000000 11111111111111111111 -var HIGH_SIGNIFICAND_MASK = 0x000fffff|0; // asm type annotation - -// 1/3 -var ONE_THIRD = 0.33333333333333333; - - -// MAIN // - -/** -* Return `log(x) - (x-1)` for `x` in `~[sqrt(2)/2, sqrt(2)]`. -* -* @private -* @param {number} x - input value -* @returns {number} function value -*/ -function klog( x ) { - var hfsq; - var t1; - var t2; - var hx; - var f; - var s; - var z; - var R; - var w; - var i; - var j; - - hx = getHighWord( x ); - f = x - 1.0; - if ( ( HIGH_SIGNIFICAND_MASK & (2+hx) ) < 3 ) { - // Case: -2**-20 <= f < 2**-20 - if ( f === 0.0 ) { - return 0.0; - } - return f * f * ( (ONE_THIRD*f) - 0.5 ); - } - s = f / ( 2.0 + f ); - z = s * s; - hx &= HIGH_SIGNIFICAND_MASK; - i = (hx - 0x6147a)|0; // asm type annotation - w = z * z; - j = (0x6b851 - hx)|0; // asm type annotation - t1 = w * polyvalP( w ); - t2 = z * polyvalQ( w ); - i |= j; - R = t2 + t1; - if ( i > 0 ) { - hfsq = 0.5 * f * f; - return ( s * (hfsq+R) ) - hfsq; - } - return s * (R-f); -} - - -// EXPORTS // - -module.exports = klog; diff --git a/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js b/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js index 5ac77dd6fad..3ead1a39ee6 100644 --- a/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js +++ b/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js @@ -18,7 +18,7 @@ * * ## Notice * -* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/9.3.0/lib/msun/src/e_log10.c}. The implementation follows the original, but has been modified for JavaScript. +* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/12.2.0/lib/msun/src/e_log10.c}. The implementation follows the original, but has been modified for JavaScript. * * ```text * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. @@ -37,10 +37,12 @@ var getHighWord = require( '@stdlib/number/float64/base/get-high-word' ); var setHighWord = require( '@stdlib/number/float64/base/set-high-word' ); var setLowWord = require( '@stdlib/number/float64/base/set-low-word' ); +var toWords = require( '@stdlib/number/float64/base/to-words' ); +var ABS_MASK = require( '@stdlib/constants/float64/high-word-abs-mask' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var BIAS = require( '@stdlib/constants/float64/exponent-bias' ); var NINF = require( '@stdlib/constants/float64/ninf' ); -var klog = require( './klog.js' ); +var kernelLog1p = require( '@stdlib/math/base/special/kernel-log1p' ); // VARIABLES // @@ -63,6 +65,9 @@ var HIGH_MIN_NORMAL_EXP = 0x00100000|0; // asm type annotation // 0x3ff00000 = 1072693248 => 0 01111111111 00000000000000000000 => biased exponent: 1023 = 0+1023 => 2^0 = 1 var HIGH_BIASED_EXP_0 = 0x3ff00000|0; // asm type annotation +// High/low words workspace: +var WORDS = [ 0|0, 0|0 ]; + // MAIN // @@ -97,49 +102,84 @@ var HIGH_BIASED_EXP_0 = 0x3ff00000|0; // asm type annotation * // returns NaN */ function log10( x ) { + var valHi; + var valLo; + var hfsq; var hi; - var hx; var lo; + var hx; + var lx; + var y2; var f; + var R; + var w; + var y; var i; var k; - var y; - var z; if ( isnan( x ) || x < 0.0 ) { return NaN; } - if ( x === 0.0 ) { - return NINF; - } - hx = getHighWord( x ); + toWords.assign( x, WORDS, 1, 0 ); + hx = WORDS[ 0 ]; + lx = WORDS[ 1 ]; k = 0|0; // asm type annotation - // Case: 0 < x < 2**-1022 if ( hx < HIGH_MIN_NORMAL_EXP ) { - // Subnormal number, scale up `x`... + // Case: x < 2**-1022 + if ( ( ( hx & ABS_MASK ) | lx ) === 0 ) { + return NINF; + } k -= 54|0; // asm type annotation + + // Subnormal number, scale up x: x *= TWO54; hx = getHighWord( x ); } if ( hx >= HIGH_MAX_NORMAL_EXP ) { return x + x; } - k += ((hx>>20) - BIAS)|0; // asm type annotation + // Case: log(1) = +0 + if ( hx === HIGH_BIASED_EXP_0 && lx === 0 ) { + return 0.0; + } + k += ( ( hx>>20 ) - BIAS )|0; // asm type annotation hx &= HIGH_SIGNIFICAND_MASK; - i = ( (hx+0x95f64)&0x100000 )|0; // asm type annotation + i = ( ( hx+0x95f64 ) & HIGH_MIN_NORMAL_EXP )|0; // asm type annotation // Normalize `x` or `x/2`... x = setHighWord( x, hx|(i^HIGH_BIASED_EXP_0) ); k += (i>>20)|0; // asm type annotation y = k; - f = klog( x ); - x -= 1; - hi = setLowWord( x, 0.0 ); - lo = x - hi; - z = (y*LOG10_2LO) + ( (x+f)*IVLN10LO ); - z += ( (lo+f)*IVLN10HI ) + ( hi*IVLN10HI ); - return z + ( y*LOG10_2HI ); + f = x - 1.0; + hfsq = 0.5 * f * f; + R = kernelLog1p( f ); + + /* + * Notes: + * + * - `f-hfsq` must (for args near `1`) be evaluated in extra precision to avoid a large cancellation when `x` is near `sqrt(2)` or `1/sqrt(2)`.This is fairly efficient since `f-hfsq` only depends on `f`, so can be evaluated in parallel with `R`. Not combining `hfsq` with `R` also keeps `R` small (though not as small as a true `lo` term would be), so that extra precision is not needed for terms involving `R`. + * - When implemented in C, compiler bugs involving extra precision used to break Dekker's theorem for spitting `f-hfsq` as `hi+lo`. These problems are now automatically avoided as a side effect of the optimization of combining the Dekker splitting step with the clear-low-bits step. + * - This implementation uses Dekker's theorem to normalize `y+val_hi`, so, when implemented in C, compiler bugs may reappear in some configurations. + * - The multi-precision calculations for the multiplications are routine. + */ + hi = f - hfsq; + hi = setLowWord( hi, 0 ); + lo = ( f - hi ) - hfsq + R; + valHi = hi * IVLN10HI; + y2 = y * LOG10_2HI; + valLo = ( y * LOG10_2LO ) + ( ( lo + hi ) * IVLN10LO ) + ( lo * IVLN10HI ); + + /* + * Note: + * + * - Extra precision in for adding y*log10_2hi is not strictly needed since there is no very large cancellation near x = sqrt(2) or x = 1/sqrt(2), but we do it anyway since it costs little on CPUs with some parallelism and it reduces the error for many args. + */ + w = y2 + valHi; + valLo += ( y2 - w ) + valHi; + valHi = w; + + return valLo + valHi; } diff --git a/lib/node_modules/@stdlib/math/base/special/log10/lib/polyval_p.js b/lib/node_modules/@stdlib/math/base/special/log10/lib/polyval_p.js deleted file mode 100644 index 520e03fbd35..00000000000 --- a/lib/node_modules/@stdlib/math/base/special/log10/lib/polyval_p.js +++ /dev/null @@ -1,47 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2022 The Stdlib Authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -/* This is a generated file. Do not edit directly. */ -'use strict'; - -// MAIN // - -/** -* Evaluates a polynomial. -* -* ## Notes -* -* - The implementation uses [Horner's rule][horners-method] for efficient computation. -* -* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method -* -* @private -* @param {number} x - value at which to evaluate the polynomial -* @returns {number} evaluated polynomial -*/ -function evalpoly( x ) { - if ( x === 0.0 ) { - return 0.3999999999940942; - } - return 0.3999999999940942 + (x * (0.22222198432149784 + (x * 0.15313837699209373))); // eslint-disable-line max-len -} - - -// EXPORTS // - -module.exports = evalpoly; diff --git a/lib/node_modules/@stdlib/math/base/special/log10/lib/polyval_q.js b/lib/node_modules/@stdlib/math/base/special/log10/lib/polyval_q.js deleted file mode 100644 index fb83e6c31d9..00000000000 --- a/lib/node_modules/@stdlib/math/base/special/log10/lib/polyval_q.js +++ /dev/null @@ -1,47 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2022 The Stdlib Authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -/* This is a generated file. Do not edit directly. */ -'use strict'; - -// MAIN // - -/** -* Evaluates a polynomial. -* -* ## Notes -* -* - The implementation uses [Horner's rule][horners-method] for efficient computation. -* -* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method -* -* @private -* @param {number} x - value at which to evaluate the polynomial -* @returns {number} evaluated polynomial -*/ -function evalpoly( x ) { - if ( x === 0.0 ) { - return 0.6666666666666735; - } - return 0.6666666666666735 + (x * (0.2857142874366239 + (x * (0.1818357216161805 + (x * 0.14798198605116586))))); // eslint-disable-line max-len -} - - -// EXPORTS // - -module.exports = evalpoly; diff --git a/lib/node_modules/@stdlib/math/base/special/log10/package.json b/lib/node_modules/@stdlib/math/base/special/log10/package.json index 4475884a88e..83d326c46f4 100644 --- a/lib/node_modules/@stdlib/math/base/special/log10/package.json +++ b/lib/node_modules/@stdlib/math/base/special/log10/package.json @@ -19,7 +19,6 @@ "doc": "./docs", "example": "./examples", "lib": "./lib", - "scripts": "./scripts", "test": "./test" }, "types": "./docs/types", diff --git a/lib/node_modules/@stdlib/math/base/special/log10/scripts/evalpoly.js b/lib/node_modules/@stdlib/math/base/special/log10/scripts/evalpoly.js deleted file mode 100644 index 89afa2c9fe6..00000000000 --- a/lib/node_modules/@stdlib/math/base/special/log10/scripts/evalpoly.js +++ /dev/null @@ -1,81 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2018 The Stdlib Authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -/* -* This script compiles modules for evaluating polynomial functions. If any polynomial coefficients change, this script should be rerun to update the compiled files. -*/ -'use strict'; - -// MODULES // - -var resolve = require( 'path' ).resolve; -var writeFileSync = require( '@stdlib/fs/write-file' ).sync; -var currentYear = require( '@stdlib/time/current-year' ); -var licenseHeader = require( '@stdlib/_tools/licenses/header' ); -var compile = require( '@stdlib/math/base/tools/evalpoly-compile' ); - - -// VARIABLES // - -// Polynomial coefficients ordered in ascending degree... -var P = [ - 3.999999999940941908e-01, // 3FD99999 9997FA04 - 2.222219843214978396e-01, // 3FCC71C5 1D8E78AF - 1.531383769920937332e-01 // 3FC39A09 D078C69F -]; -var Q = [ - 6.666666666666735130e-01, // 3FE55555 55555593 - 2.857142874366239149e-01, // 3FD24924 94229359 - 1.818357216161805012e-01, // 3FC74664 96CB03DE - 1.479819860511658591e-01 // 3FC2F112 DF3E5244 -]; - -// Header to add to output files: -var header = licenseHeader( 'Apache-2.0', 'js', { - 'year': currentYear(), - 'copyright': 'The Stdlib Authors' -}); -header += '\n/* This is a generated file. Do not edit directly. */\n'; - - -// MAIN // - -/** -* Main execution sequence. -* -* @private -*/ -function main() { - var fpath; - var opts; - var str; - - opts = { - 'encoding': 'utf8' - }; - - fpath = resolve( __dirname, '..', 'lib', 'polyval_p.js' ); - str = header + compile( P ); - writeFileSync( fpath, str, opts ); - - fpath = resolve( __dirname, '..', 'lib', 'polyval_q.js' ); - str = header + compile( Q ); - writeFileSync( fpath, str, opts ); -} - -main(); diff --git a/lib/node_modules/@stdlib/math/base/special/log10/test/test.js b/lib/node_modules/@stdlib/math/base/special/log10/test/test.js index 4b693b57324..2e7b53554d9 100644 --- a/lib/node_modules/@stdlib/math/base/special/log10/test/test.js +++ b/lib/node_modules/@stdlib/math/base/special/log10/test/test.js @@ -26,6 +26,7 @@ var PINF = require( '@stdlib/constants/float64/pinf' ); var NINF = require( '@stdlib/constants/float64/ninf' ); var EPS = require( '@stdlib/constants/float64/eps' ); var abs = require( '@stdlib/math/base/special/abs' ); +var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' ); var log10 = require( './../lib' ); @@ -224,3 +225,9 @@ tape( 'the function returns `NaN` if provided a negative number', function test( t.equal( isnan( v ), true, 'returns NaN' ); t.end(); }); + +tape( 'the function returns positive zero if provided `1.0`', function test( t ) { + var v = log10( 1.0 ); + t.equal( isPositiveZero( v ), true, 'returns +0' ); + t.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/log10/test/test.klog.js b/lib/node_modules/@stdlib/math/base/special/log10/test/test.klog.js deleted file mode 100644 index 69edb949c4d..00000000000 --- a/lib/node_modules/@stdlib/math/base/special/log10/test/test.klog.js +++ /dev/null @@ -1,50 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2018 The Stdlib Authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -'use strict'; - -// MODULES // - -var tape = require( 'tape' ); -var pow = require( '@stdlib/math/base/special/pow' ); -var klog = require( './../lib/klog.js' ); - - -// TESTS // - -tape( 'main export is a function', function test( t ) { - t.ok( true, __filename ); - t.strictEqual( typeof klog, 'function', 'main export is a function' ); - t.end(); -}); - -tape( 'the function returns `0.0` if provided `x = 1`', function test( t ) { - var y = klog( 1.0 ); - t.equal( y, 0.0, 'returns 0.0' ); - t.end(); -}); - -tape( 'the function correctly computes `log(x) - (x-1)` for `x` satisfying `-2**-20 <= x-1 < 2**-20`', function test( t ) { - var y = klog( 1.0 + pow( 2.0, -20.0 ) ); - t.equal( y, -4.547470617660916e-13, 'returns correct value' ); - - y = klog( 1.0 + pow( -2.0, -20.0 ) ); - t.equal( y, -4.547470617660916e-13, 'returns correct value' ); - - t.end(); -}); From 75b111b22ec34e59bd11d0997765df6bcf47eb7f Mon Sep 17 00:00:00 2001 From: GUNJ JOSHI Date: Tue, 16 Apr 2024 12:07:43 +0530 Subject: [PATCH 2/3] Update main.js Signed-off-by: GUNJ JOSHI --- .../@stdlib/math/base/special/log10/lib/main.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js b/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js index 3ead1a39ee6..ec3d2dee10e 100644 --- a/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js +++ b/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js @@ -143,13 +143,13 @@ function log10( x ) { if ( hx === HIGH_BIASED_EXP_0 && lx === 0 ) { return 0.0; } - k += ( ( hx>>20 ) - BIAS )|0; // asm type annotation + k += ( ( hx >> 20 ) - BIAS )|0; // asm type annotation hx &= HIGH_SIGNIFICAND_MASK; - i = ( ( hx+0x95f64 ) & HIGH_MIN_NORMAL_EXP )|0; // asm type annotation + i = ( ( hx + 0x95f64 ) & HIGH_MIN_NORMAL_EXP )|0; // asm type annotation // Normalize `x` or `x/2`... - x = setHighWord( x, hx|(i^HIGH_BIASED_EXP_0) ); - k += (i>>20)|0; // asm type annotation + x = setHighWord( x, hx | ( i ^ HIGH_BIASED_EXP_0 ) ); + k += ( i >> 20 )|0; // asm type annotation y = k; f = x - 1.0; hfsq = 0.5 * f * f; From 140abfc54f32b23daa7fb680d3136bbd407cb5b2 Mon Sep 17 00:00:00 2001 From: Athan Reines Date: Tue, 16 Apr 2024 01:25:28 -0700 Subject: [PATCH 3/3] refactor: use constant package and update comment --- .../@stdlib/math/base/special/log10/lib/main.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js b/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js index ec3d2dee10e..50eb8bbdcdb 100644 --- a/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js +++ b/lib/node_modules/@stdlib/math/base/special/log10/lib/main.js @@ -39,6 +39,7 @@ var setHighWord = require( '@stdlib/number/float64/base/set-high-word' ); var setLowWord = require( '@stdlib/number/float64/base/set-low-word' ); var toWords = require( '@stdlib/number/float64/base/to-words' ); var ABS_MASK = require( '@stdlib/constants/float64/high-word-abs-mask' ); +var HIGH_SIGNIFICAND_MASK = require( '@stdlib/constants/float64/high-word-significand-mask' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var BIAS = require( '@stdlib/constants/float64/exponent-bias' ); var NINF = require( '@stdlib/constants/float64/ninf' ); @@ -53,9 +54,6 @@ var IVLN10LO = 2.50829467116452752298e-11; // 0x3dbb9438, 0xca9aadd5 var LOG10_2HI = 3.01029995663611771306e-01; // 0x3FD34413, 0x509F6000 var LOG10_2LO = 3.69423907715893078616e-13; // 0x3D59FEF3, 0x11F12B36 -// 0x000fffff = 1048575 => 0 00000000000 11111111111111111111 -var HIGH_SIGNIFICAND_MASK = 0x000fffff|0; // asm type annotation - // 0x7ff00000 = 2146435072 => 0 11111111111 00000000000000000000 => biased exponent: 2047 = 1023+1023 => 2^1023 var HIGH_MAX_NORMAL_EXP = 0x7ff00000|0; // asm type annotation @@ -173,7 +171,7 @@ function log10( x ) { /* * Note: * - * - Extra precision in for adding y*log10_2hi is not strictly needed since there is no very large cancellation near x = sqrt(2) or x = 1/sqrt(2), but we do it anyway since it costs little on CPUs with some parallelism and it reduces the error for many args. + * - Extra precision in for adding `y*log10_2hi` is not strictly needed since there is no very large cancellation near `x = sqrt(2)` or `x = 1/sqrt(2)`, but we do it anyway since it costs little on CPUs with some parallelism and it reduces the error for many args. */ w = y2 + valHi; valLo += ( y2 - w ) + valHi;