Skip to content

Commit 66f7bba

Browse files
gunjjoshikgryte
andauthored
refactor!: modify C implementation to accept double instead of int32 in math/base/special/bernoulli
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: #7940 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]>
1 parent 248ba46 commit 66f7bba

File tree

8 files changed

+30
-28
lines changed

8 files changed

+30
-28
lines changed

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,19 +154,19 @@ for ( i = 0; i < 280; i++ ) {
154154
Computes the nth [Bernoulli number][bernoulli-number].
155155

156156
```c
157-
double out = stdlib_base_bernoulli( 0 );
157+
double out = stdlib_base_bernoulli( 0.0 );
158158
// returns 1.0
159159

160-
out = stdlib_base_bernoulli( 1 );
160+
out = stdlib_base_bernoulli( 1.0 );
161161
// returns 0.5
162162
```
163163

164164
The function accepts the following arguments:
165165

166-
- **n**: `[in] int32_t` input value.
166+
- **n**: `[in] double` input value.
167167

168168
```c
169-
double stdlib_base_bernoulli( const int32_t n );
169+
double stdlib_base_bernoulli( const double n );
170170
```
171171
172172
</section>
@@ -190,15 +190,14 @@ double stdlib_base_bernoulli( const int32_t n );
190190
```c
191191
#include "stdlib/math/base/special/bernoulli.h"
192192
#include <stdio.h>
193-
#include <stdint.h>
194193
195194
int main( void ) {
196-
int32_t i;
195+
double i;
197196
double v;
198197
199-
for ( i = 0; i < 130; i++ ) {
198+
for ( i = 0.0; i < 130.0; i++ ) {
200199
v = stdlib_base_bernoulli( i );
201-
printf( "bernoulli(%d) = %lf\n", i, v );
200+
printf( "bernoulli(%lf) = %lf\n", i, v );
202201
}
203202
}
204203
```

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ static double benchmark( void ) {
102102

103103
t = tic();
104104
for ( i = 0; i < ITERATIONS; i++ ) {
105-
y = stdlib_base_bernoulli( (int)( x[ i % 100 ] ) );
105+
y = stdlib_base_bernoulli( ( x[ i % 100 ] ) );
106106
if ( y != y ) {
107107
printf( "should not return NaN\n" );
108108
break;

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@
1818

1919
#include "stdlib/math/base/special/bernoulli.h"
2020
#include <stdio.h>
21-
#include <stdint.h>
2221

2322
int main( void ) {
24-
int32_t i;
23+
double i;
2524
double v;
2625

27-
for ( i = 0; i < 130; i++ ) {
26+
for ( i = 0.0; i < 130.0; i++ ) {
2827
v = stdlib_base_bernoulli( i );
29-
printf( "bernoulli(%d) = %lf\n", i, v );
28+
printf( "bernoulli(%lf) = %lf\n", i, v );
3029
}
3130
}

lib/node_modules/@stdlib/math/base/special/bernoulli/include/stdlib/math/base/special/bernoulli.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_BERNOULLI_H
2020
#define STDLIB_MATH_BASE_SPECIAL_BERNOULLI_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 nth Bernoulli number.
3331
*/
34-
double stdlib_base_bernoulli( const int32_t n );
32+
double stdlib_base_bernoulli( const double n );
3533

3634
#ifdef __cplusplus
3735
}

lib/node_modules/@stdlib/math/base/special/bernoulli/lib/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ function bernoulli( n ) {
9292
return 0.0;
9393
}
9494
if ( n > MAX_BERNOULLI ) {
95-
return ( (n/2)&1 ) ? PINF : NINF;
95+
return ( isOdd( n/2.0 ) ) ? PINF : NINF;
9696
}
9797
return BERNOULLI[ n/2 ];
9898
}

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"@stdlib/math/base/napi/unary",
4040
"@stdlib/math/base/assert/is-odd",
4141
"@stdlib/constants/float64/ninf",
42-
"@stdlib/constants/float64/pinf"
42+
"@stdlib/constants/float64/pinf",
43+
"@stdlib/math/base/assert/is-nonnegative-integer"
4344
]
4445
},
4546
{
@@ -55,7 +56,8 @@
5556
"dependencies": [
5657
"@stdlib/math/base/assert/is-odd",
5758
"@stdlib/constants/float64/ninf",
58-
"@stdlib/constants/float64/pinf"
59+
"@stdlib/constants/float64/pinf",
60+
"@stdlib/math/base/assert/is-nonnegative-integer"
5961
]
6062
},
6163
{
@@ -71,7 +73,8 @@
7173
"dependencies": [
7274
"@stdlib/math/base/assert/is-odd",
7375
"@stdlib/constants/float64/ninf",
74-
"@stdlib/constants/float64/pinf"
76+
"@stdlib/constants/float64/pinf",
77+
"@stdlib/math/base/assert/is-nonnegative-integer"
7578
]
7679
}
7780
]

lib/node_modules/@stdlib/math/base/special/bernoulli/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/bernoulli.h"
2020
#include "stdlib/math/base/napi/unary.h"
2121

22-
STDLIB_MATH_BASE_NAPI_MODULE_I_D( stdlib_base_bernoulli )
22+
STDLIB_MATH_BASE_NAPI_MODULE_D_D( stdlib_base_bernoulli )

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

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616
* limitations under the License.
1717
*/
1818

19+
#include "stdlib/math/base/assert/is_nonnegative_integer.h"
1920
#include "stdlib/math/base/assert/is_odd.h"
2021
#include "stdlib/constants/float64/ninf.h"
2122
#include "stdlib/constants/float64/pinf.h"
2223
#include "stdlib/math/base/special/bernoulli.h"
24+
#include <stdint.h>
25+
#include <stdlib.h>
2326

2427
static const double bernoulli_value[ 130 ] = {
2528
1.00000000000000000000000000000000000000000,
@@ -164,21 +167,21 @@ int32_t MAX_BERNOULLI = 258;
164167
* @return output value
165168
*
166169
* @example
167-
* double out = stdlib_base_bernoulli( 0 );
168-
* // returns 1
170+
* double out = stdlib_base_bernoulli( 0.0 );
171+
* // returns 1.0
169172
*/
170-
double stdlib_base_bernoulli( const int32_t n ) {
171-
if ( n < 0 ) {
173+
double stdlib_base_bernoulli( const double n ) {
174+
if ( !stdlib_base_is_nonnegative_integer( n ) ) {
172175
return 0.0 / 0.0; // NaN
173176
}
174-
if ( n == 1 ) {
177+
if ( n == 1.0 ) {
175178
return 0.5;
176179
}
177180
if ( stdlib_base_is_odd( n ) ) {
178181
return 0.0;
179182
}
180183
if ( n > MAX_BERNOULLI ) {
181-
return ( ( n / 2 ) & 1 ) ? STDLIB_CONSTANT_FLOAT64_PINF : STDLIB_CONSTANT_FLOAT64_NINF;
184+
return ( stdlib_base_is_odd( n/2.0 ) ) ? STDLIB_CONSTANT_FLOAT64_PINF : STDLIB_CONSTANT_FLOAT64_NINF;
182185
}
183-
return bernoulli_value[ n / 2 ];
186+
return bernoulli_value[ (size_t)( n / 2.0 ) ];
184187
}

0 commit comments

Comments
 (0)