From 3aa23c499e7f498a4950ed7e73345044611d4e72 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 3 Sep 2026 12:39:11 +0000 Subject: [PATCH 1/4] fix: perform support checks before integer narrowing in `stats/base/dists/hypergeometric/cdf` The C implementation cast `x` to `int32_t` before comparing against the distribution support, so finite values outside int32 range invoked undefined conversion behavior and returned 0.0 instead of 1.0 (e.g., `cdf( 1.0e10, 20, 20, 10 )`). Perform the bound comparisons in double space and only narrow once the value is guaranteed in range, matching the JavaScript implementation. Also restores the parameter clause in the function doc comment to match `cdf.h` and `lib/native.js`. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01E8PkS1AQnkLGgAAEiFeQq7 --- .../stats/base/dists/hypergeometric/cdf/src/main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c index 7abaa6c41175..11a77996ced0 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c @@ -26,7 +26,7 @@ #include /** -* Evaluates the cumulative distribution function (CDF) for a hypergeometric distribution. +* Evaluates the cumulative distribution function (CDF) for a hypergeometric distribution with population size `N`, subpopulation size `K`, and number of draws `n` at a value `x`. * * @param x input value * @param N population size @@ -47,6 +47,7 @@ double stdlib_base_dists_hypergeometric_cdf( double denom; double num; double ret; + double xd; double p; int32_t upper; int32_t lower; @@ -67,17 +68,18 @@ double stdlib_base_dists_hypergeometric_cdf( return ( x > 0.0 ) ? 1.0 : 0.0; } - xi = (int32_t)stdlib_base_trunc( x ); + xd = stdlib_base_trunc( x ); lower = stdlib_base_max( 0, n + K - N ); upper = stdlib_base_min( n, K ); - if ( xi < lower ) { + if ( xd < (double)lower ) { return 0.0; } - if ( xi >= upper ) { + if ( xd >= (double)upper ) { return 1.0; } + xi = (int32_t)xd; p = stdlib_base_dists_hypergeometric_pmf( (double)xi, N, K, n ); ret = p; From 0eb14a0ece0e94ded46e1cbe9202fe3eb19db44e Mon Sep 17 00:00:00 2001 From: Athan Date: Thu, 3 Sep 2026 22:20:05 -0700 Subject: [PATCH 2/4] style: reorder variables Signed-off-by: Athan --- .../stats/base/dists/hypergeometric/cdf/src/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c index 11a77996ced0..d182cbe5224e 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c @@ -44,15 +44,15 @@ double stdlib_base_dists_hypergeometric_cdf( const int32_t K, const int32_t n ) { + int32_t upper; + int32_t lower; double denom; + int32_t xi; double num; double ret; + int32_t i; double xd; double p; - int32_t upper; - int32_t lower; - int32_t xi; - int32_t i; if ( stdlib_base_is_nan( x ) || From 174dc1ebc589646b3013a004f4370cd77ecab46b Mon Sep 17 00:00:00 2001 From: Athan Date: Thu, 3 Sep 2026 22:27:14 -0700 Subject: [PATCH 3/4] refactor: clean-up Signed-off-by: Athan --- .../base/dists/hypergeometric/cdf/src/main.c | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c index d182cbe5224e..df97a20012de 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c @@ -38,21 +38,18 @@ * double y = stdlib_base_dists_hypergeometric_cdf( 1.0, 8, 4, 2 ); * // returns ~0.786 */ -double stdlib_base_dists_hypergeometric_cdf( - const double x, - const int32_t N, - const int32_t K, - const int32_t n -) { - int32_t upper; - int32_t lower; +double stdlib_base_dists_hypergeometric_cdf( const double x, const int32_t N, const int32_t K, const int32_t n ) { + double upper; + double lower; double denom; - int32_t xi; double num; double ret; - int32_t i; - double xd; + double dx; + double dn; + double dK; + double dN; double p; + double i; if ( stdlib_base_is_nan( x ) || @@ -62,31 +59,28 @@ double stdlib_base_dists_hypergeometric_cdf( K > N || n > N ) { - return 0.0 / 0.0; + return 0.0 / 0.0; // NaN } if ( stdlib_base_is_infinite( x ) ) { return ( x > 0.0 ) ? 1.0 : 0.0; } - - xd = stdlib_base_trunc( x ); - - lower = stdlib_base_max( 0, n + K - N ); - upper = stdlib_base_min( n, K ); - - if ( xd < (double)lower ) { + dn = (double)n; + dN = (double)N; + dK = (double)K; + dx = stdlib_base_trunc( x ); + lower = stdlib_base_max( 0.0, dn+dK-dN ); + upper = stdlib_base_min( dn, dK ); + if ( dx < lower ) { return 0.0; } - if ( xd >= (double)upper ) { + if ( dx >= upper ) { return 1.0; } - xi = (int32_t)xd; - - p = stdlib_base_dists_hypergeometric_pmf( (double)xi, N, K, n ); + p = stdlib_base_dists_hypergeometric_pmf( dx, N, K, n ); ret = p; - - for ( i = xi - 1; i >= lower; i-- ) { - num = (double)( i + 1 ) * (double)( N - K - ( n - i - 1 ) ); - denom = (double)( K - i ) * (double)( n - i ); + for ( i = dx-1.0; i >= lower; i -= 1.0 ) { + num = ( i + 1.0 ) * ( dN - dK - dn + i + 1.0 ) ); + denom = ( dK - i ) * ( dn - i ); p = ( num / denom ) * p; ret += p; } From 6d394b68a35e6bdc1467eb633b0da6bbcee37036 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 08:00:11 +0000 Subject: [PATCH 4/4] fix: remove stray parenthesis in `stats/base/dists/hypergeometric/cdf` Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01E8PkS1AQnkLGgAAEiFeQq7 --- .../@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c b/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c index df97a20012de..a28d2158b77d 100644 --- a/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c +++ b/lib/node_modules/@stdlib/stats/base/dists/hypergeometric/cdf/src/main.c @@ -79,7 +79,7 @@ double stdlib_base_dists_hypergeometric_cdf( const double x, const int32_t N, co p = stdlib_base_dists_hypergeometric_pmf( dx, N, K, n ); ret = p; for ( i = dx-1.0; i >= lower; i -= 1.0 ) { - num = ( i + 1.0 ) * ( dN - dK - dn + i + 1.0 ) ); + num = ( i + 1.0 ) * ( dN - dK - dn + i + 1.0 ); denom = ( dK - i ) * ( dn - i ); p = ( num / denom ) * p; ret += p;