Skip to content

Commit 134c514

Browse files
gunjjoshikgryte
andauthored
refactor!: modify C implementation to accept double instead of int32 in math/base/special/tribonacci
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: #8031 Co-authored-by: Athan Reines <kgryte@gmail.com> Reviewed-by: Athan Reines <kgryte@gmail.com>
1 parent dc3487c commit 134c514

9 files changed

Lines changed: 55 additions & 31 deletions

File tree

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,19 @@ for ( i = 0; i < 64; i++ ) {
176176
Computes the nth [Tribonacci number][tribonacci-number].
177177

178178
```c
179-
double out = stdlib_base_tribonacci( 0 );
180-
// returns 0
179+
double out = stdlib_base_tribonacci( 0.0 );
180+
// returns 0.0
181181

182-
out = stdlib_base_tribonacci( 1 );
183-
// returns 0
182+
out = stdlib_base_tribonacci( 1.0 );
183+
// returns 0.0
184184
```
185185

186186
The function accepts the following arguments:
187187

188-
- **n**: `[in] int32_t` input value.
188+
- **n**: `[in] double` input value.
189189

190190
```c
191-
double stdlib_base_tribonacci( const int32_t n );
191+
double stdlib_base_tribonacci( const double n );
192192
```
193193
194194
</section>
@@ -212,15 +212,14 @@ double stdlib_base_tribonacci( const int32_t n );
212212
```c
213213
#include "stdlib/math/base/special/tribonacci.h"
214214
#include <stdio.h>
215-
#include <stdint.h>
216215
217216
int main( void ) {
218-
int32_t i;
217+
double i;
219218
double v;
220219
221-
for ( i = 0; i < 64; i++ ) {
220+
for ( i = 0.0; i < 64.0; i++ ) {
222221
v = stdlib_base_tribonacci( i );
223-
printf( "tribonacci(%d) = %lf\n", i, v );
222+
printf( "tribonacci(%lf) = %lf\n", i, v );
224223
}
225224
}
226225
```

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,14 @@ static double rand_double( void ) {
9090
* @return elapsed time in seconds
9191
*/
9292
static double benchmark( void ) {
93-
int32_t x[ 100 ];
93+
double x[ 100 ];
9494
double elapsed;
9595
double t;
9696
double y;
9797
int i;
9898

9999
for ( i = 0; i < 100; i++ ) {
100-
x[ i ] = (int32_t)floor( 40.0*rand_double() );
100+
x[ i ] = floor( 40.0*rand_double() );
101101
}
102102

103103
t = tic();

lib/node_modules/@stdlib/math/base/special/tribonacci/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/tribonacci.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 < 64; i++ ) {
26+
for ( i = 0.0; i < 64.0; i++ ) {
2827
v = stdlib_base_tribonacci( i );
29-
printf( "tribonacci(%d) = %lf\n", i, v );
28+
printf( "tribonacci(%lf) = %lf\n", i, v );
3029
}
3130
}

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

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

22-
#include <stdint.h>
23-
2422
#ifdef __cplusplus
2523
extern "C" {
2624
#endif
2725

2826
/**
2927
* Computes the nth Tribonacci number.
3028
*/
31-
double stdlib_base_tribonacci( const int32_t n );
29+
double stdlib_base_tribonacci( const double n );
3230

3331
#ifdef __cplusplus
3432
};

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
// MODULES //
2222

2323
var isnan = require( '@stdlib/math/base/assert/is-nan' );
24-
var isInteger = require( '@stdlib/math/base/assert/is-integer' );
24+
var isNonnegativeInteger = require( '@stdlib/math/base/assert/is-nonnegative-integer' );
2525
var FLOAT64_MAX_SAFE_NTH_TRIBONACCI = require( '@stdlib/constants/float64/max-safe-nth-tribonacci' ); // eslint-disable-line id-length
2626
var TRIBONACCI = require( './tribonacci.json' );
2727

@@ -77,8 +77,7 @@ var TRIBONACCI = require( './tribonacci.json' );
7777
function tribonacci( n ) {
7878
if (
7979
isnan( n ) ||
80-
isInteger( n ) === false ||
81-
n < 0 ||
80+
!isNonnegativeInteger( n ) ||
8281
n > FLOAT64_MAX_SAFE_NTH_TRIBONACCI
8382
) {
8483
return NaN;

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
"libpath": [],
3838
"dependencies": [
3939
"@stdlib/math/base/napi/unary",
40-
"@stdlib/constants/float64/max-safe-nth-tribonacci"
40+
"@stdlib/constants/float64/max-safe-nth-tribonacci",
41+
"@stdlib/math/base/assert/is-nan",
42+
"@stdlib/math/base/assert/is-nonnegative-integer"
4143
]
4244
},
4345
{
@@ -51,7 +53,9 @@
5153
"libraries": [],
5254
"libpath": [],
5355
"dependencies": [
54-
"@stdlib/constants/float64/max-safe-nth-tribonacci"
56+
"@stdlib/constants/float64/max-safe-nth-tribonacci",
57+
"@stdlib/math/base/assert/is-nan",
58+
"@stdlib/math/base/assert/is-nonnegative-integer"
5559
]
5660
},
5761
{
@@ -65,7 +69,9 @@
6569
"libraries": [],
6670
"libpath": [],
6771
"dependencies": [
68-
"@stdlib/constants/float64/max-safe-nth-tribonacci"
72+
"@stdlib/constants/float64/max-safe-nth-tribonacci",
73+
"@stdlib/math/base/assert/is-nan",
74+
"@stdlib/math/base/assert/is-nonnegative-integer"
6975
]
7076
}
7177
]

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

22-
STDLIB_MATH_BASE_NAPI_MODULE_I_D( stdlib_base_tribonacci )
22+
STDLIB_MATH_BASE_NAPI_MODULE_D_D( stdlib_base_tribonacci )

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818

1919
#include "stdlib/math/base/special/tribonacci.h"
2020
#include "stdlib/constants/float64/max_safe_nth_tribonacci.h"
21+
#include "stdlib/math/base/assert/is_nonnegative_integer.h"
22+
#include "stdlib/math/base/assert/is_nan.h"
23+
#include <stdlib.h>
24+
#include <stdint.h>
2125

2226
static const int64_t tribonacci_value[ 64 ] = {
2327
0,
@@ -93,12 +97,12 @@ static const int64_t tribonacci_value[ 64 ] = {
9397
* @return output value
9498
*
9599
* @example
96-
* double out = stdlib_base_tribonacci( 1 );
97-
* // returns 0
100+
* double out = stdlib_base_tribonacci( 1.0 );
101+
* // returns 0.0
98102
*/
99-
double stdlib_base_tribonacci( const int32_t n ) {
100-
if ( n < 0 || n > STDLIB_CONSTANT_FLOAT64_MAX_SAFE_NTH_TRIBONACCI ) {
103+
double stdlib_base_tribonacci( const double n ) {
104+
if ( stdlib_base_is_nan( n ) || !stdlib_base_is_nonnegative_integer( n ) || n > STDLIB_CONSTANT_FLOAT64_MAX_SAFE_NTH_TRIBONACCI ) {
101105
return 0.0 / 0.0; // NaN
102106
}
103-
return tribonacci_value[ n ];
107+
return tribonacci_value[ (size_t)n ];
104108
}

lib/node_modules/@stdlib/math/base/special/tribonacci/test/test.native.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
var resolve = require( 'path' ).resolve;
2424
var tape = require( 'tape' );
2525
var isnan = require( '@stdlib/math/base/assert/is-nan' );
26+
var PINF = require( '@stdlib/constants/float64/pinf' );
2627
var tryRequire = require( '@stdlib/utils/try-require' );
2728

2829

@@ -58,6 +59,24 @@ tape( 'if provided a negative number, the function returns `NaN`', opts, functio
5859
t.end();
5960
});
6061

62+
tape( 'if provided positive infinity, the function returns `NaN`', opts, function test( t ) {
63+
var v = tribonacci( PINF );
64+
t.strictEqual( isnan( v ), true, 'returns expected value' );
65+
t.end();
66+
});
67+
68+
tape( 'if provided `NaN`, the function returns `NaN`', opts, function test( t ) {
69+
var v = tribonacci( NaN );
70+
t.strictEqual( isnan( v ), true, 'returns expected value' );
71+
t.end();
72+
});
73+
74+
tape( 'if provided a non-integer, the function returns `NaN`', opts, function test( t ) {
75+
var v = tribonacci( 3.14 );
76+
t.strictEqual( isnan( v ), true, 'returns expected value' );
77+
t.end();
78+
});
79+
6180
tape( 'the function returns the nth Tribonacci number', opts, function test( t ) {
6281
var v;
6382
var i;

0 commit comments

Comments
 (0)