Skip to content

Commit 0681f24

Browse files
authored
refactor!: modify C implementation to accept double values instead of int64 in math/base/special/binomcoefln
This commit updates the signature of the C API to accept a double rather than int32. The rationale was so that users get the same results/behavior in both JavaScript and C. This arose in the context of ufuncs, where the diverging type signatures meant differences in what dtypes would be permissible. Instead, we decided to unify and ensure the behavior is consistent. BREAKING CHANGE: update signature to accept doubles User code should behave similarly in the primary case of providing integer-valued input values. However, no longer will real-values truncate. Now, real-valued inputs will result in `NaN`, which is, arguably, better behavior, as real-to-integer truncation can be a source of silent bugs. PR-URL: #7947 Reviewed-by: Athan Reines <[email protected]>
1 parent d109efc commit 0681f24

File tree

7 files changed

+30
-30
lines changed

7 files changed

+30
-30
lines changed

lib/node_modules/@stdlib/math/base/special/binomcoefln/README.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,17 +187,17 @@ logEachMap( 'ln( %d choose %d ) = %0.4f', n, k, binomcoefln );
187187
Evaluates the natural logarithm of the [binomial coefficient][binomial-coefficient] of two integers `n` and `k`.
188188

189189
```c
190-
double v = stdlib_base_binomcoefln( 8, 2 );
190+
double v = stdlib_base_binomcoefln( 8.0, 2.0 );
191191
// returns ~3.332
192192
```
193193

194194
The function accepts the following arguments:
195195

196-
- **n**: `[in] int64_t` input value.
197-
- **k**: `[in] int64_t` input value.
196+
- **n**: `[in] double` input value.
197+
- **k**: `[in] double` input value.
198198

199199
```c
200-
double stdlib_base_binomcoefln( const int64_t n, const int64_t k );
200+
double stdlib_base_binomcoefln( const double n, const double k );
201201
```
202202
203203
</section>
@@ -221,18 +221,16 @@ double stdlib_base_binomcoefln( const int64_t n, const int64_t k );
221221
```c
222222
#include "stdlib/math/base/special/binomcoefln.h"
223223
#include <stdio.h>
224-
#include <stdint.h>
225-
#include <inttypes.h>
226224
227225
int main( void ) {
228-
const int64_t a[] = { 24, 32, 48, 116, 33 };
229-
const int64_t b[] = { 12, 6, 15, 52, 22 };
226+
const double a[] = { 24.0, 32.0, 48.0, 116.0, 33.0 };
227+
const double b[] = { 12.0, 6.0, 15.0, 52.0, 22.0 };
230228
231229
double out;
232230
int i;
233231
for ( i = 0; i < 5; i++ ) {
234232
out = stdlib_base_binomcoefln( a[ i ], b[ i ] );
235-
printf( "binomcoefln(%" PRId64 ", %" PRId64 ") = %lf\n", a[ i ], b[ i ], out );
233+
printf( "binomcoefln(%lf, %lf) = %lf\n", a[ i ], b[ i ], out );
236234
}
237235
}
238236
```

lib/node_modules/@stdlib/math/base/special/binomcoefln/benchmark/c/native/benchmark.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,16 @@ static double rand_double( void ) {
9090
* @return elapsed time in seconds
9191
*/
9292
static double benchmark( void ) {
93-
int64_t n[ 100 ];
94-
int64_t k[ 100 ];
93+
double n[ 100 ];
94+
double k[ 100 ];
9595
double elapsed;
9696
double y;
9797
double t;
9898
int i;
9999

100100
for ( i = 0; i < 100; i++ ) {
101-
n[ i ] = (int64_t)round( 500.0 * rand_double() );
102-
k[ i ] = (int64_t)round( 500.0 * rand_double() );
101+
n[ i ] = round( 500.0 * rand_double() );
102+
k[ i ] = round( 500.0 * rand_double() );
103103
}
104104

105105
t = tic();

lib/node_modules/@stdlib/math/base/special/binomcoefln/examples/c/example.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,15 @@
1818

1919
#include "stdlib/math/base/special/binomcoefln.h"
2020
#include <stdio.h>
21-
#include <stdint.h>
22-
#include <inttypes.h>
2321

2422
int main( void ) {
25-
const int64_t a[] = { 24, 32, 48, 116, 33 };
26-
const int64_t b[] = { 12, 6, 15, 52, 22 };
23+
const double a[] = { 24.0, 32.0, 48.0, 116.0, 33.0 };
24+
const double b[] = { 12.0, 6.0, 15.0, 52.0, 22.0 };
2725

2826
double out;
2927
int i;
3028
for ( i = 0; i < 5; i++ ) {
3129
out = stdlib_base_binomcoefln( a[ i ], b[ i ] );
32-
printf( "binomcoefln(%" PRId64 ", %" PRId64 ") = %lf\n", a[ i ], b[ i ], out );
30+
printf( "binomcoefln(%lf, %lf) = %lf\n", a[ i ], b[ i ], out );
3331
}
3432
}

lib/node_modules/@stdlib/math/base/special/binomcoefln/include/stdlib/math/base/special/binomcoefln.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
#ifndef STDLIB_MATH_BASE_SPECIAL_BINOMCOEFLN_H
2020
#define STDLIB_MATH_BASE_SPECIAL_BINOMCOEFLN_H
2121

22-
#include <stdint.h>
23-
2422
/*
2523
* If C++, prevent name mangling so that the compiler emits a binary file having undecorated names, thus mirroring the behavior of a C compiler.
2624
*/
@@ -31,7 +29,7 @@ extern "C" {
3129
/**
3230
* Computes the natural logarithm of the binomial coefficient of two integers.
3331
*/
34-
double stdlib_base_binomcoefln( const int64_t n, const int64_t k );
32+
double stdlib_base_binomcoefln( const double n, const double k );
3533

3634
#ifdef __cplusplus
3735
}

lib/node_modules/@stdlib/math/base/special/binomcoefln/manifest.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"@stdlib/math/base/special/betaln",
4343
"@stdlib/math/base/special/abs",
4444
"@stdlib/math/base/special/ln",
45-
"@stdlib/constants/float64/ninf"
45+
"@stdlib/constants/float64/ninf",
46+
"@stdlib/math/base/assert/is-integer"
4647
]
4748
},
4849
{
@@ -61,7 +62,8 @@
6162
"@stdlib/math/base/special/betaln",
6263
"@stdlib/math/base/special/abs",
6364
"@stdlib/math/base/special/ln",
64-
"@stdlib/constants/float64/ninf"
65+
"@stdlib/constants/float64/ninf",
66+
"@stdlib/math/base/assert/is-integer"
6567
]
6668
},
6769
{
@@ -80,7 +82,8 @@
8082
"@stdlib/math/base/special/betaln",
8183
"@stdlib/math/base/special/abs",
8284
"@stdlib/math/base/special/ln",
83-
"@stdlib/constants/float64/ninf"
85+
"@stdlib/constants/float64/ninf",
86+
"@stdlib/math/base/assert/is-integer"
8487
]
8588
}
8689
]

lib/node_modules/@stdlib/math/base/special/binomcoefln/src/addon.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@
1919
#include "stdlib/math/base/special/binomcoefln.h"
2020
#include "stdlib/math/base/napi/binary.h"
2121

22-
STDLIB_MATH_BASE_NAPI_MODULE_LL_D( stdlib_base_binomcoefln )
22+
STDLIB_MATH_BASE_NAPI_MODULE_DD_D( stdlib_base_binomcoefln )

lib/node_modules/@stdlib/math/base/special/binomcoefln/src/main.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
*/
1818

1919
#include "stdlib/math/base/special/binomcoefln.h"
20+
#include "stdlib/math/base/assert/is_integer.h"
2021
#include "stdlib/math/base/special/betaln.h"
2122
#include "stdlib/math/base/special/abs.h"
2223
#include "stdlib/math/base/special/ln.h"
2324
#include "stdlib/constants/float64/ninf.h"
24-
#include <stdint.h>
2525

2626
/**
2727
* Computes the natural logarithm of the binomial coefficient of two integers.
@@ -31,10 +31,13 @@
3131
* @return function value
3232
*
3333
* @example
34-
* double out = stdlib_base_binomcoefln( 8, 2 );
34+
* double out = stdlib_base_binomcoefln( 8.0, 2.0 );
3535
* // returns ~3.332
3636
*/
37-
double stdlib_base_binomcoefln( const int64_t n, const int64_t k ) {
37+
double stdlib_base_binomcoefln( const double n, const double k ) {
38+
if ( !stdlib_base_is_integer( n ) || !stdlib_base_is_integer( k ) ) {
39+
return 0.0 / 0.0; // NaN
40+
}
3841
if ( n < 0 ) {
3942
return stdlib_base_binomcoefln( -n + k - 1, k );
4043
}
@@ -45,7 +48,7 @@ double stdlib_base_binomcoefln( const int64_t n, const int64_t k ) {
4548
return 0.0;
4649
}
4750
if ( k == 1 ) {
48-
return stdlib_base_ln( stdlib_base_abs( (double)n ) );
51+
return stdlib_base_ln( stdlib_base_abs( n ) );
4952
}
5053
if ( n < k ) {
5154
return STDLIB_CONSTANT_FLOAT64_NINF;
@@ -55,5 +58,5 @@ double stdlib_base_binomcoefln( const int64_t n, const int64_t k ) {
5558
}
5659

5760
// Case: n - k >= 2
58-
return -stdlib_base_ln( (double)(n + 1) ) - stdlib_base_betaln( (double)(n - k + 1), (double)(k + 1) );
61+
return -stdlib_base_ln( ( n + 1 ) ) - stdlib_base_betaln( ( n - k + 1 ), ( k + 1 ) );
5962
}

0 commit comments

Comments
 (0)