From 6781f0d5a1af07cfc8cd344a64f4df59cc21f0e1 Mon Sep 17 00:00:00 2001 From: 0PrashantYadav0 Date: Tue, 20 Oct 2026 18:49:49 +0530 Subject: [PATCH 1/2] fix: return subnormal values in `math/base/special/exp2` and `exp10` --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown_pkg_readmes status: na - task: lint_markdown_docs status: na - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: missing_dependencies - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../math/base/special/exp10/lib/main.js | 2 +- .../math/base/special/exp10/manifest.json | 6 +++--- .../math/base/special/exp10/src/main.c | 4 ++-- .../math/base/special/exp10/test/test.js | 21 +++++++++++++++++++ .../base/special/exp10/test/test.native.js | 20 ++++++++++++++++++ .../math/base/special/exp2/lib/main.js | 4 ++-- .../math/base/special/exp2/manifest.json | 8 +++---- .../@stdlib/math/base/special/exp2/src/main.c | 4 ++-- .../math/base/special/exp2/test/test.js | 19 +++++++++++++++++ .../base/special/exp2/test/test.native.js | 19 +++++++++++++++++ 10 files changed, 93 insertions(+), 14 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/exp10/lib/main.js b/lib/node_modules/@stdlib/math/base/special/exp10/lib/main.js index a4c086eae198..8b6e17b692f2 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp10/lib/main.js +++ b/lib/node_modules/@stdlib/math/base/special/exp10/lib/main.js @@ -38,7 +38,7 @@ var floor = require( '@stdlib/math/base/special/floor' ); var ldexp = require( '@stdlib/math/base/special/ldexp' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var MAXL10 = require( '@stdlib/constants/float64/max-base10-exponent' ); -var MINL10 = require( '@stdlib/constants/float64/min-base10-exponent' ); +var MINL10 = require( '@stdlib/constants/float64/min-base10-exponent-subnormal' ); var PINF = require( '@stdlib/constants/float64/pinf' ); var polyvalP = require( './polyval_p.js' ); var polyvalQ = require( './polyval_q.js' ); diff --git a/lib/node_modules/@stdlib/math/base/special/exp10/manifest.json b/lib/node_modules/@stdlib/math/base/special/exp10/manifest.json index 89e4c46efeae..02f1fe024445 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp10/manifest.json +++ b/lib/node_modules/@stdlib/math/base/special/exp10/manifest.json @@ -42,7 +42,7 @@ "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/floor", "@stdlib/math/base/special/ldexp", - "@stdlib/constants/float64/min-base10-exponent", + "@stdlib/constants/float64/min-base10-exponent-subnormal", "@stdlib/constants/float64/nan" ] }, @@ -62,7 +62,7 @@ "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/floor", "@stdlib/math/base/special/ldexp", - "@stdlib/constants/float64/min-base10-exponent", + "@stdlib/constants/float64/min-base10-exponent-subnormal", "@stdlib/constants/float64/nan" ] }, @@ -82,7 +82,7 @@ "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/floor", "@stdlib/math/base/special/ldexp", - "@stdlib/constants/float64/min-base10-exponent", + "@stdlib/constants/float64/min-base10-exponent-subnormal", "@stdlib/constants/float64/nan" ] } diff --git a/lib/node_modules/@stdlib/math/base/special/exp10/src/main.c b/lib/node_modules/@stdlib/math/base/special/exp10/src/main.c index 42ff65360c46..e4743b0b3d7a 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp10/src/main.c +++ b/lib/node_modules/@stdlib/math/base/special/exp10/src/main.c @@ -35,7 +35,7 @@ #include "stdlib/math/base/special/ldexp.h" #include "stdlib/math/base/assert/is_nan.h" #include "stdlib/constants/float64/max_base10_exponent.h" -#include "stdlib/constants/float64/min_base10_exponent.h" +#include "stdlib/constants/float64/min_base10_exponent_subnormal.h" #include "stdlib/constants/float64/pinf.h" #include "stdlib/constants/float64/nan.h" #include @@ -129,7 +129,7 @@ double stdlib_base_exp10( const double x ) { if ( x > STDLIB_CONSTANT_FLOAT64_MAX_BASE10_EXPONENT ) { return STDLIB_CONSTANT_FLOAT64_PINF; } - if ( x < STDLIB_CONSTANT_FLOAT64_MIN_BASE10_EXPONENT ) { + if ( x < STDLIB_CONSTANT_FLOAT64_MIN_BASE10_EXPONENT_SUBNORMAL ) { return 0.0; } // Express 10^x = 10^g 2^n = 10^g 10^( n log10(2) ) = 10^( g + n log10(2) ) diff --git a/lib/node_modules/@stdlib/math/base/special/exp10/test/test.js b/lib/node_modules/@stdlib/math/base/special/exp10/test/test.js index 7e6441bcf1f3..2645516ff2f3 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp10/test/test.js +++ b/lib/node_modules/@stdlib/math/base/special/exp10/test/test.js @@ -25,6 +25,7 @@ var isnan = require( '@stdlib/math/base/assert/is-nan' ); var PINF = require( '@stdlib/constants/float64/pinf' ); var NINF = require( '@stdlib/constants/float64/ninf' ); var isPositiveZero = require( '@stdlib/assert/is-positive-zero' ); +var isAlmostSameValue = require( '@stdlib/assert/is-almost-same-value' ); var exp10 = require( './../lib' ); @@ -167,3 +168,23 @@ tape( 'the function returns `NaN` if provided `NaN`', function test( t ) { t.strictEqual( isnan( val ), true, 'equals NaN' ); t.end(); }); + +tape( 'the function returns subnormal values for `x` in the subnormal range', function test( t ) { + var expected; + var x; + var v; + var i; + + x = [ -308.5, -310.0, -320.0, -323.5 ]; + expected = [ + 3.16227766016838e-309, + 1e-310, + 1e-320, + 5e-324 + ]; + for ( i = 0; i < x.length; i++ ) { + v = exp10( x[ i ] ); + t.strictEqual( isAlmostSameValue( v, expected[ i ], 1 ), true, 'returns expected value' ); + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/exp10/test/test.native.js b/lib/node_modules/@stdlib/math/base/special/exp10/test/test.native.js index e3adf1d9f764..f643aa28240a 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp10/test/test.native.js +++ b/lib/node_modules/@stdlib/math/base/special/exp10/test/test.native.js @@ -181,3 +181,23 @@ tape( 'the function returns `NaN` if provided `NaN`', opts, function test( t ) { t.strictEqual( isnan( val ), true, 'equals NaN' ); t.end(); }); + +tape( 'the function returns subnormal values for `x` in the subnormal range', opts, function test( t ) { + var expected; + var x; + var v; + var i; + + x = [ -308.5, -310.0, -320.0, -323.5 ]; + expected = [ + 3.16227766016838e-309, + 1e-310, + 1e-320, + 5e-324 + ]; + for ( i = 0; i < x.length; i++ ) { + v = exp10( x[ i ] ); + t.strictEqual( isAlmostSameValue( v, expected[ i ], 1 ), true, 'returns expected value' ); + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js b/lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js index ed01a638747f..73b3d170c9d6 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js +++ b/lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js @@ -37,7 +37,7 @@ // MODULES // var FLOAT64_MAX_BASE2_EXPONENT = require( '@stdlib/constants/float64/max-base2-exponent' ); // eslint-disable-line id-length -var FLOAT64_MIN_BASE2_EXPONENT = require( '@stdlib/constants/float64/min-base2-exponent' ); // eslint-disable-line id-length +var FLOAT64_MIN_BASE2_EXPONENT_SUBNORMAL = require( '@stdlib/constants/float64/min-base2-exponent-subnormal' ); // eslint-disable-line id-length var round = require( '@stdlib/math/base/special/round' ); var ldexp = require( '@stdlib/math/base/special/ldexp' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); @@ -104,7 +104,7 @@ function exp2( x ) { if ( x > FLOAT64_MAX_BASE2_EXPONENT ) { return PINF; } - if ( x < FLOAT64_MIN_BASE2_EXPONENT ) { + if ( x < FLOAT64_MIN_BASE2_EXPONENT_SUBNORMAL ) { return 0.0; } // Separate into integer and fractional parts... diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/manifest.json b/lib/node_modules/@stdlib/math/base/special/exp2/manifest.json index a2adffecfdb4..3e41db2a664f 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/manifest.json +++ b/lib/node_modules/@stdlib/math/base/special/exp2/manifest.json @@ -44,7 +44,7 @@ "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/round", "@stdlib/math/base/special/ldexp", - "@stdlib/constants/float64/min-base2-exponent" + "@stdlib/constants/float64/min-base2-exponent-subnormal" ] }, { @@ -64,7 +64,7 @@ "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/round", "@stdlib/math/base/special/ldexp", - "@stdlib/constants/float64/min-base2-exponent" + "@stdlib/constants/float64/min-base2-exponent-subnormal" ] }, { @@ -84,7 +84,7 @@ "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/round", "@stdlib/math/base/special/ldexp", - "@stdlib/constants/float64/min-base2-exponent" + "@stdlib/constants/float64/min-base2-exponent-subnormal" ] }, { @@ -104,7 +104,7 @@ "@stdlib/constants/float64/pinf", "@stdlib/math/base/special/round", "@stdlib/math/base/special/ldexp", - "@stdlib/constants/float64/min-base2-exponent" + "@stdlib/constants/float64/min-base2-exponent-subnormal" ] } ] diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/src/main.c b/lib/node_modules/@stdlib/math/base/special/exp2/src/main.c index a913467e70f6..d00fc6dab8f8 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/src/main.c +++ b/lib/node_modules/@stdlib/math/base/special/exp2/src/main.c @@ -32,7 +32,7 @@ #include "stdlib/math/base/special/exp2.h" #include "stdlib/constants/float64/max_base2_exponent.h" -#include "stdlib/constants/float64/min_base2_exponent.h" +#include "stdlib/constants/float64/min_base2_exponent_subnormal.h" #include "stdlib/math/base/special/round.h" #include "stdlib/math/base/special/ldexp.h" #include "stdlib/math/base/assert/is_nan.h" @@ -128,7 +128,7 @@ double stdlib_base_exp2( const double x ) { if ( x > STDLIB_CONSTANT_FLOAT64_MAX_BASE2_EXPONENT ) { return STDLIB_CONSTANT_FLOAT64_PINF; } - if ( x < STDLIB_CONSTANT_FLOAT64_MIN_BASE2_EXPONENT ) { + if ( x < STDLIB_CONSTANT_FLOAT64_MIN_BASE2_EXPONENT_SUBNORMAL ) { return 0.0; } diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/test/test.js b/lib/node_modules/@stdlib/math/base/special/exp2/test/test.js index 8ebf5cba93a9..f0e50b098329 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/test/test.js +++ b/lib/node_modules/@stdlib/math/base/special/exp2/test/test.js @@ -168,3 +168,22 @@ tape( 'the function returns `NaN` if provided `NaN`', function test( t ) { t.strictEqual( isnan( val ), true, 'equals NaN' ); t.end(); }); + +tape( 'the function returns subnormal values for `x` in the subnormal range', function test( t ) { + var expected; + var x; + var v; + var i; + + x = [ -1023.5, -1050.0, -1074.0 ]; + expected = [ + 7.866824069956793e-309, + 8.289046e-317, + 5e-324 + ]; + for ( i = 0; i < x.length; i++ ) { + v = exp2( x[ i ] ); + t.strictEqual( isAlmostSameValue( v, expected[ i ], 1 ), true, 'returns expected value' ); + } + t.end(); +}); diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/test/test.native.js b/lib/node_modules/@stdlib/math/base/special/exp2/test/test.native.js index 0f928d20a0d6..d99d3d367927 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/test/test.native.js +++ b/lib/node_modules/@stdlib/math/base/special/exp2/test/test.native.js @@ -177,3 +177,22 @@ tape( 'the function returns `NaN` if provided `NaN`', opts, function test( t ) { t.strictEqual( isnan( val ), true, 'equals NaN' ); t.end(); }); + +tape( 'the function returns subnormal values for `x` in the subnormal range', opts, function test( t ) { + var expected; + var x; + var v; + var i; + + x = [ -1023.5, -1050.0, -1074.0 ]; + expected = [ + 7.866824069956793e-309, + 8.289046e-317, + 5e-324 + ]; + for ( i = 0; i < x.length; i++ ) { + v = exp2( x[ i ] ); + t.strictEqual( isAlmostSameValue( v, expected[ i ], 1 ), true, 'returns expected value' ); + } + t.end(); +}); From 3998a1c779b43a5733ce9ef8d93b5551624c8b1e Mon Sep 17 00:00:00 2001 From: 0PrashantYadav0 Date: Mon, 26 Oct 2026 22:19:43 +0530 Subject: [PATCH 2/2] fix: return subnormal values for `-1075 < x < -1074` in `math/base/special/exp2` --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown_pkg_readmes status: na - task: lint_markdown_docs status: na - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: missing_dependencies - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js | 3 ++- lib/node_modules/@stdlib/math/base/special/exp2/src/main.c | 3 ++- lib/node_modules/@stdlib/math/base/special/exp2/test/test.js | 1 + .../@stdlib/math/base/special/exp2/test/test.native.js | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js b/lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js index 73b3d170c9d6..531dc55a568b 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js +++ b/lib/node_modules/@stdlib/math/base/special/exp2/lib/main.js @@ -104,7 +104,8 @@ function exp2( x ) { if ( x > FLOAT64_MAX_BASE2_EXPONENT ) { return PINF; } - if ( x < FLOAT64_MIN_BASE2_EXPONENT_SUBNORMAL ) { + // Note: values on the interval `(-1075, -1074)` round to the smallest subnormal... + if ( x <= FLOAT64_MIN_BASE2_EXPONENT_SUBNORMAL-1 ) { return 0.0; } // Separate into integer and fractional parts... diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/src/main.c b/lib/node_modules/@stdlib/math/base/special/exp2/src/main.c index d00fc6dab8f8..4ba63c994df5 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/src/main.c +++ b/lib/node_modules/@stdlib/math/base/special/exp2/src/main.c @@ -128,7 +128,8 @@ double stdlib_base_exp2( const double x ) { if ( x > STDLIB_CONSTANT_FLOAT64_MAX_BASE2_EXPONENT ) { return STDLIB_CONSTANT_FLOAT64_PINF; } - if ( x < STDLIB_CONSTANT_FLOAT64_MIN_BASE2_EXPONENT_SUBNORMAL ) { + // Note: values on the interval `(-1075, -1074)` round to the smallest subnormal... + if ( x <= STDLIB_CONSTANT_FLOAT64_MIN_BASE2_EXPONENT_SUBNORMAL-1 ) { return 0.0; } diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/test/test.js b/lib/node_modules/@stdlib/math/base/special/exp2/test/test.js index f0e50b098329..05fb27838ae5 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/test/test.js +++ b/lib/node_modules/@stdlib/math/base/special/exp2/test/test.js @@ -134,6 +134,7 @@ tape( 'the function returns `+infinity` for very large `x`', function test( t ) }); tape( 'the function returns `0.0` for negative large `x`', function test( t ) { + t.strictEqual( exp2( -1075.0 ), 0.0, 'equals 0' ); t.strictEqual( exp2( -1100.0 ), 0.0, 'equals 0' ); t.strictEqual( exp2( -1200.0 ), 0.0, 'equals 0' ); t.strictEqual( exp2( -1300.0 ), 0.0, 'equals 0' ); diff --git a/lib/node_modules/@stdlib/math/base/special/exp2/test/test.native.js b/lib/node_modules/@stdlib/math/base/special/exp2/test/test.native.js index d99d3d367927..d457065be763 100644 --- a/lib/node_modules/@stdlib/math/base/special/exp2/test/test.native.js +++ b/lib/node_modules/@stdlib/math/base/special/exp2/test/test.native.js @@ -143,6 +143,7 @@ tape( 'the function returns `+infinity` for very large `x`', opts, function test }); tape( 'the function returns `0.0` for negative large `x`', opts, function test( t ) { + t.strictEqual( exp2( -1075.0 ), 0.0, 'equals 0' ); t.strictEqual( exp2( -1100.0 ), 0.0, 'equals 0' ); t.strictEqual( exp2( -1200.0 ), 0.0, 'equals 0' ); t.strictEqual( exp2( -1300.0 ), 0.0, 'equals 0' );