Skip to content

Commit 59f0fbb

Browse files
gunjjoshikgryte
andauthored
refactor!: modify C implementation to accept float instead of int32 in math/base/special/bernoullif
This commit updates the signature of the C API to accept a float 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 floats 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: #7941 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]>
1 parent 66f7bba commit 59f0fbb

File tree

8 files changed

+35
-31
lines changed

8 files changed

+35
-31
lines changed

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,19 +156,19 @@ logEachMap( 'bernoullif(%d) = %0.4f', x, bernoullif );
156156
Computes the nth [Bernoulli number][bernoulli-number] as a single-precision floating-point number.
157157

158158
```c
159-
float out = stdlib_base_bernoullif( 0 );
159+
float out = stdlib_base_bernoullif( 0.0f );
160160
// returns 1.0f
161161

162-
out = stdlib_base_bernoullif( 1 );
162+
out = stdlib_base_bernoullif( 1.0f );
163163
// returns 0.5f
164164
```
165165

166166
The function accepts the following arguments:
167167

168-
- **n**: `[in] int32_t` input value.
168+
- **n**: `[in] float` input value.
169169

170170
```c
171-
float stdlib_base_bernoullif( const int32_t n );
171+
float stdlib_base_bernoullif( const float n );
172172
```
173173
174174
</section>
@@ -192,15 +192,14 @@ float stdlib_base_bernoullif( const int32_t n );
192192
```c
193193
#include "stdlib/math/base/special/bernoullif.h"
194194
#include <stdio.h>
195-
#include <stdint.h>
196195
197196
int main( void ) {
198-
int32_t i;
197+
float i;
199198
float v;
200199
201-
for ( i = 0; i < 70; i++ ) {
200+
for ( i = 0.0f; i < 70.0f; i++ ) {
202201
v = stdlib_base_bernoullif( i );
203-
printf( "bernoullif(%d) = %f\n", i, v );
202+
printf( "bernoullif(%f) = %f\n", i, v );
204203
}
205204
}
206205
```

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
#include "stdlib/math/base/special/bernoullif.h"
2020
#include <stdlib.h>
21-
#include <stdint.h>
2221
#include <stdio.h>
2322
#include <math.h>
2423
#include <time.h>
@@ -103,7 +102,7 @@ static double benchmark( void ) {
103102

104103
t = tic();
105104
for ( i = 0; i < ITERATIONS; i++ ) {
106-
y = stdlib_base_bernoullif( (int32_t)( x[ i%100 ] ) );
105+
y = stdlib_base_bernoullif( ( x[ i%100 ] ) );
107106
if ( y != y ) {
108107
printf( "should not return NaN\n" );
109108
break;

lib/node_modules/@stdlib/math/base/special/bernoullif/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/bernoullif.h"
2020
#include <stdio.h>
21-
#include <stdint.h>
2221

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

27-
for ( i = 0; i < 70; i++ ) {
26+
for ( i = 0.0f; i < 70.0f; i++ ) {
2827
v = stdlib_base_bernoullif( i );
29-
printf( "bernoullif(%d) = %f\n", i, v );
28+
printf( "bernoullif(%f) = %f\n", i, v );
3029
}
3130
}

lib/node_modules/@stdlib/math/base/special/bernoullif/include/stdlib/math/base/special/bernoullif.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_BERNOULLIF_H
2020
#define STDLIB_MATH_BASE_SPECIAL_BERNOULLIF_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 as a single-precision floating-point number.
3331
*/
34-
float stdlib_base_bernoullif( const int32_t n );
32+
float stdlib_base_bernoullif( const float n );
3533

3634
#ifdef __cplusplus
3735
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
var isNonNegativeIntegerf = require( '@stdlib/math/base/assert/is-nonnegative-integerf' );
2424
var float64ToFloat32 = require( '@stdlib/number/float64/base/to-float32' );
2525
var isnanf = require( '@stdlib/math/base/assert/is-nanf' );
26-
var isOdd = require( '@stdlib/math/base/assert/is-odd' );
26+
var isOddf = require( '@stdlib/math/base/assert/is-oddf' );
2727
var NINF = require( '@stdlib/constants/float32/ninf' );
2828
var PINF = require( '@stdlib/constants/float32/pinf' );
2929
var BERNOULLIF = require( './bernoullif.json' );
@@ -89,11 +89,11 @@ function bernoullif( n ) {
8989
if ( n === 1 ) {
9090
return 0.5;
9191
}
92-
if ( isOdd( n ) ) {
92+
if ( isOddf( n ) ) {
9393
return 0.0;
9494
}
9595
if ( n > MAX_BERNOULLI ) {
96-
return ( (n/2)&1 ) ? PINF : NINF;
96+
return ( isOddf( n/2.0 ) ) ? PINF : NINF;
9797
}
9898
return float64ToFloat32( BERNOULLIF[ n/2 ] );
9999
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
"dependencies": [
3939
"@stdlib/math/base/napi/unary",
4040
"@stdlib/constants/float32/ninf",
41-
"@stdlib/constants/float32/pinf"
41+
"@stdlib/constants/float32/pinf",
42+
"@stdlib/math/base/assert/is-nonnegative-integerf",
43+
"@stdlib/math/base/assert/is-oddf"
4244
]
4345
},
4446
{
@@ -53,7 +55,9 @@
5355
"libpath": [],
5456
"dependencies": [
5557
"@stdlib/constants/float32/ninf",
56-
"@stdlib/constants/float32/pinf"
58+
"@stdlib/constants/float32/pinf",
59+
"@stdlib/math/base/assert/is-nonnegative-integerf",
60+
"@stdlib/math/base/assert/is-oddf"
5761
]
5862
},
5963
{
@@ -68,7 +72,9 @@
6872
"libpath": [],
6973
"dependencies": [
7074
"@stdlib/constants/float32/ninf",
71-
"@stdlib/constants/float32/pinf"
75+
"@stdlib/constants/float32/pinf",
76+
"@stdlib/math/base/assert/is-nonnegative-integerf",
77+
"@stdlib/math/base/assert/is-oddf"
7278
]
7379
}
7480
]

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

22-
STDLIB_MATH_BASE_NAPI_MODULE_I_F( stdlib_base_bernoullif )
22+
STDLIB_MATH_BASE_NAPI_MODULE_F_F( stdlib_base_bernoullif )

lib/node_modules/@stdlib/math/base/special/bernoullif/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_integerf.h"
20+
#include "stdlib/math/base/assert/is_oddf.h"
1921
#include "stdlib/math/base/special/bernoullif.h"
2022
#include "stdlib/constants/float32/ninf.h"
2123
#include "stdlib/constants/float32/pinf.h"
2224
#include <stdint.h>
25+
#include <stdlib.h>
2326

2427
static const float bernoulli_value[ 33 ] = {
2528
1.0f,
@@ -66,21 +69,21 @@ static const int32_t MAX_BERNOULLI = 64;
6669
* @return output value
6770
*
6871
* @example
69-
* float out = stdlib_base_bernoullif( 0 );
72+
* float out = stdlib_base_bernoullif( 0.0f );
7073
* // returns 1.0f
7174
*/
72-
float stdlib_base_bernoullif( const int32_t n ) {
73-
if ( n < 0 ) {
75+
float stdlib_base_bernoullif( const float n ) {
76+
if ( !stdlib_base_is_nonnegative_integerf( n ) ) {
7477
return 0.0f / 0.0f; // NaN
7578
}
76-
if ( n == 1 ) {
79+
if ( n == 1.0f ) {
7780
return 0.5f;
7881
}
79-
if ( n & 1 ) {
82+
if ( stdlib_base_is_oddf( n ) ) {
8083
return 0.0f;
8184
}
8285
if ( n > MAX_BERNOULLI ) {
83-
return ( ( n / 2 ) & 1 ) ? STDLIB_CONSTANT_FLOAT32_PINF : STDLIB_CONSTANT_FLOAT32_NINF;
86+
return ( stdlib_base_is_oddf( n/2.0f ) ) ? STDLIB_CONSTANT_FLOAT32_PINF : STDLIB_CONSTANT_FLOAT32_NINF;
8487
}
85-
return bernoulli_value[ n / 2 ];
88+
return bernoulli_value[ (size_t)( n / 2.0f ) ];
8689
}

0 commit comments

Comments
 (0)