Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: update math/base/special/log2 to follow FreeBSD version 12.2.0 #2172

Merged
merged 3 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 0 additions & 102 deletions lib/node_modules/@stdlib/math/base/special/log2/lib/klog.js

This file was deleted.

50 changes: 40 additions & 10 deletions lib/node_modules/@stdlib/math/base/special/log2/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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_log2.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_log2.c}. The implementation follows the original, but has been modified for JavaScript.
*
* ```text
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Expand All @@ -43,7 +43,7 @@ var ABS_MASK = require( '@stdlib/constants/float64/high-word-abs-mask' );
var HIGH_SIGNIFICAND_MASK = require( '@stdlib/constants/float64/high-word-significand-mask' );
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 //
Expand Down Expand Up @@ -98,11 +98,17 @@ var WORDS = [ 0|0, 0|0 ];
* // returns NaN
*/
function log2( x ) {
var hi;
var lo;
var valHi;
var valLo;
var hfsq;
var hx;
var lx;
var hi;
var lo;
var f;
var R;
var w;
var y;
var i;
var k;

Expand All @@ -127,18 +133,42 @@ function log2( x ) {
if ( hx >= HIGH_MAX_NORMAL_EXP ) {
return x + x;
}
// 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
f = klog( x );
x -= 1;
hi = setLowWord( x, 0 );
lo = x - hi;
return ( (x+f)*IVLN2LO ) + ( (lo+f)*IVLN2HI ) + ( hi*IVLN2HI ) + k;
y = k;
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.
* - `y` must (for args near `sqrt(2)` and `1/sqrt(2)`) be added in extra precision to avoid a very large cancellation when `x` is very near these values. Unlike the above cancellations, this problem is specific to base `2`. It is strange that adding `+-1` is so much harder than adding `+-ln2` or `+-log10_2`.
* - 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 * IVLN2HI;
valLo = ( ( lo + hi ) * IVLN2LO ) + ( lo * IVLN2HI );

w = y + valHi;
valLo += ( y - w ) + valHi;
valHi = w;

return valLo + valHi;
}


Expand Down
47 changes: 0 additions & 47 deletions lib/node_modules/@stdlib/math/base/special/log2/lib/polyval_p.js

This file was deleted.

47 changes: 0 additions & 47 deletions lib/node_modules/@stdlib/math/base/special/log2/lib/polyval_q.js

This file was deleted.

9 changes: 6 additions & 3 deletions lib/node_modules/@stdlib/math/base/special/log2/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"@stdlib/constants/float64/high-word-abs-mask",
"@stdlib/constants/float64/high-word-significand-mask",
"@stdlib/constants/float64/exponent-bias",
"@stdlib/constants/float64/ninf"
"@stdlib/constants/float64/ninf",
"@stdlib/math/base/special/kernel-log1p"
]
},
{
Expand All @@ -67,7 +68,8 @@
"@stdlib/constants/float64/high-word-abs-mask",
"@stdlib/constants/float64/high-word-significand-mask",
"@stdlib/constants/float64/exponent-bias",
"@stdlib/constants/float64/ninf"
"@stdlib/constants/float64/ninf",
"@stdlib/math/base/special/kernel-log1p"
]
},
{
Expand All @@ -89,7 +91,8 @@
"@stdlib/constants/float64/high-word-abs-mask",
"@stdlib/constants/float64/high-word-significand-mask",
"@stdlib/constants/float64/exponent-bias",
"@stdlib/constants/float64/ninf"
"@stdlib/constants/float64/ninf",
"@stdlib/math/base/special/kernel-log1p"
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"example": "./examples",
"include": "./include",
"lib": "./lib",
"scripts": "./scripts",
"src": "./src",
"test": "./test"
},
Expand Down
Loading
Loading