Skip to content

Commit 55b6b8a

Browse files
committed
Add support for providing an output array
1 parent aaee8e0 commit 55b6b8a

File tree

7 files changed

+194
-24
lines changed

7 files changed

+194
-24
lines changed

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

+18-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
var modf = require( '@stdlib/math/base/special/modf' );
1111
```
1212

13-
#### modf( x )
13+
#### modf( \[out,] x )
1414

1515
Decomposes a [double-precision floating-point number][ieee754] into integral and fractional parts, each having the same type and sign as `x`.
1616

@@ -34,7 +34,23 @@ parts = modf( NaN );
3434
// returns [ NaN, NaN ]
3535
```
3636

37-
<section class="usage">
37+
To avoid unnecessary memory allocation, the function supports providing an output (destination) object.
38+
39+
```javascript
40+
var Float64Array = require( '@stdlib/array/float64' );
41+
42+
var out = new Float64Array( 2 );
43+
44+
var parts = modf( out, 3.14 );
45+
// returns [ 3.0, 0.14000000000000012 ]
46+
47+
var bool = ( parts === out );
48+
// returns true
49+
```
50+
51+
</section>
52+
53+
<!-- /.usage -->
3854

3955
<section class="notes">
4056

lib/node_modules/@stdlib/math/base/special/modf/benchmark/benchmark.js

+24
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,27 @@ bench( pkg, function benchmark( b ) {
3131
b.pass( 'benchmark finished' );
3232
b.end();
3333
});
34+
35+
bench( pkg+'::memory_reuse', function benchmark( b ) {
36+
var out;
37+
var x;
38+
var y;
39+
var i;
40+
41+
out = [ 0.0, 0.0 ];
42+
43+
b.tic();
44+
for ( i = 0; i < b.iterations; i++ ) {
45+
x = ( randu()*1.0e7 ) - 5.0e6;
46+
y = modf( out, x );
47+
if ( !isArray( y ) ) {
48+
b.fail( 'should return an array' );
49+
}
50+
}
51+
b.toc();
52+
if ( !isArray( y ) || y !== out ) {
53+
b.fail( 'should return the output array' );
54+
}
55+
b.pass( 'benchmark finished' );
56+
b.end();
57+
});

lib/node_modules/@stdlib/math/base/special/modf/docs/repl.txt

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11

2-
{{alias}}( x )
2+
{{alias}}( [out,] x )
33
Decomposes a double-precision floating-point number into integral and
44
fractional parts, each having the same type and sign as the input value.
55

66
Parameters
77
----------
8+
out: Array|TypedArray|Object (optional)
9+
Output array.
10+
811
x: number
912
Input value.
1013

1114
Returns
1215
-------
13-
parts: Array<double>
14-
Array containing integral and fractional parts.
16+
parts: Array|TypedArray|Object
17+
Integral and fractional parts.
1518

1619
Examples
1720
--------
@@ -30,6 +33,13 @@
3033
> parts = {{alias}}( NaN )
3134
[ NaN, NaN ]
3235

36+
// Provide an output array:
37+
> var out = new {{alias:@stdlib/array/float64}}( 2 );
38+
> parts = {{alias}}( 3.14 )
39+
<Float64Array>[ 3.0, 0.14000000000000012 ]
40+
> var bool = ( parts === out )
41+
true
42+
3343
See Also
3444
--------
3545

lib/node_modules/@stdlib/math/base/special/modf/lib/index.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,23 @@
1010
*
1111
* var parts = modf( 3.14 );
1212
* // returns [ 3.0, 0.14000000000000012 ]
13+
*
14+
* @example
15+
* var Float64Array = require( '@stdlib/array/float64' );
16+
* var modf = require( '@stdlib/math/base/special/modf' );
17+
*
18+
* var out = new Float64Array( 2 );
19+
*
20+
* var parts = modf( out, 3.14 );
21+
* // returns [ 3.0, 0.14000000000000012 ]
22+
*
23+
* var bool = ( parts === out );
24+
* // returns true
1325
*/
1426

1527
// MODULES //
1628

17-
var modf = require( './modf.js' );
29+
var modf = require( './main.js' );
1830

1931

2032
// EXPORTS //
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
// MODULES //
4+
5+
var fcn = require( './modf.js' );
6+
7+
8+
// MAIN //
9+
10+
/**
11+
* Decomposes a double-precision floating-point number into integral and fractional parts, each having the same type and sign as the input value.
12+
*
13+
* @param {(Array|TypedArray|Object)} [out] - output array
14+
* @param {number} x - input value
15+
* @returns {(Array|TypedArray|Object)} output array
16+
*
17+
* @example
18+
* var parts = modf( 3.14 );
19+
* // returns [ 3.0, 0.14000000000000012 ]
20+
*
21+
* @example
22+
* var Float64Array = require( '@stdlib/array/float64' );
23+
*
24+
* var out = new Float64Array( 2 );
25+
*
26+
* var parts = modf( out, 3.14 );
27+
* // returns <Float64Array>[ 3.0, 0.14000000000000012 ]
28+
*
29+
* var bool = ( parts === out );
30+
* // returns true
31+
*/
32+
function modf( out, x ) {
33+
if ( arguments.length === 1 ) {
34+
return fcn( new Array( 2 ), out );
35+
}
36+
return fcn( out, x );
37+
} // end FUNCTION modf()
38+
39+
40+
// EXPORTS //
41+
42+
module.exports = modf;

lib/node_modules/@stdlib/math/base/special/modf/lib/modf.js

+37-18
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@ var WORDS = [ 0, 0 ]; // WARNING: not thread safe
2525
/**
2626
* Decomposes a double-precision floating-point number into integral and fractional parts, each having the same type and sign as the input value.
2727
*
28+
* @private
29+
* @param {(Array|TypedArray|Object)} out - output array
2830
* @param {number} x - input value
29-
* @returns {NumberArray} array containing integral and fractional parts
31+
* @returns {(Array|TypedArray|Object)} output array
3032
*
3133
* @example
32-
* var parts = modf( 3.14 );
34+
* var parts = modf( new Array( 2 ), 3.14 );
3335
* // returns [ 3.0, 0.14000000000000012 ]
3436
*/
35-
function modf( x ) {
36-
var parts;
37+
function modf( out, x ) {
3738
var high;
3839
var low;
3940
var exp;
@@ -42,21 +43,29 @@ function modf( x ) {
4243
// Special cases...
4344
if ( x < 1.0 ) {
4445
if ( x < 0.0 ) {
45-
parts = modf( -x );
46-
parts[ 0 ] *= -1.0;
47-
parts[ 1 ] *= -1.0;
48-
return parts;
46+
modf( out, -x );
47+
out[ 0 ] *= -1.0;
48+
out[ 1 ] *= -1.0;
49+
return out;
4950
}
50-
if ( x === 0.0 ) {
51-
return [ x, x ]; // [ +-0, +-0 ]
51+
if ( x === 0.0 ) { // [ +-0, +-0 ]
52+
out[ 0 ] = x;
53+
out[ 1 ] = x;
54+
return out;
5255
}
53-
return [ 0.0, x ];
56+
out[ 0 ] = 0.0;
57+
out[ 1 ] = x;
58+
return out;
5459
}
5560
if ( isnan( x ) ) {
56-
return [ NaN, NaN ];
61+
out[ 0 ] = NaN;
62+
out[ 1 ] = NaN;
63+
return out;
5764
}
5865
if ( x === PINF ) {
59-
return [ PINF, 0.0 ];
66+
out[ 0 ] = PINF;
67+
out[ 1 ] = 0.0;
68+
return out;
6069
}
6170
// Decompose |x|...
6271

@@ -75,7 +84,9 @@ function modf( x ) {
7584

7685
// Determine if `x` is integral by checking for significand bits which cannot be exponentiated away...
7786
if ( ((high&i)|low) === 0 ) {
78-
return [ x, 0.0 ];
87+
out[ 0 ] = x;
88+
out[ 1 ] = 0.0;
89+
return out;
7990
}
8091
// Turn off all the bits which cannot be exponentiated away:
8192
high &= (~i);
@@ -84,18 +95,24 @@ function modf( x ) {
8495
i = fromWords( high, 0 );
8596

8697
// The fractional part is whatever is leftover:
87-
return [ i, x-i ];
98+
out[ 0 ] = i;
99+
out[ 1 ] = x - i;
100+
return out;
88101
}
89102
// Check if `x` can even have a fractional part...
90103
if ( exp > 51 ) {
91104
// `x` is integral:
92-
return [ x, 0.0 ];
105+
out[ 0 ] = x;
106+
out[ 1 ] = 0.0;
107+
return out;
93108
}
94109
i = ALL_ONES >>> (exp-20);
95110

96111
// Determine if `x` is integral by checking for less significant significand bits which cannot be exponentiated away...
97112
if ( (low&i) === 0 ) {
98-
return [ x, 0.0 ];
113+
out[ 0 ] = x;
114+
out[ 1 ] = 0.0;
115+
return out;
99116
}
100117
// Turn off all the bits which cannot be exponentiated away:
101118
low &= (~i);
@@ -104,7 +121,9 @@ function modf( x ) {
104121
i = fromWords( high, low );
105122

106123
// The fractional part is whatever is leftover:
107-
return [ i, x-i ];
124+
out[ 0 ] = i;
125+
out[ 1 ] = x - i;
126+
return out;
108127
} // end FUNCTION modf()
109128

110129

lib/node_modules/@stdlib/math/base/special/modf/test/test.js

+47
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ var NINF = require( '@stdlib/constants/math/float64-ninf' );
88
var isNegativeZero = require( '@stdlib/math/base/assert/is-negative-zero' );
99
var isPositiveZero = require( '@stdlib/math/base/assert/is-positive-zero' );
1010
var isnan = require( '@stdlib/math/base/assert/is-nan' );
11+
var Float64Array = require( '@stdlib/array/float64' );
1112
var modf = require( './../lib' );
1213

1314

@@ -152,3 +153,49 @@ tape( 'if provided `NaN`, the function returns `[NaN,NaN]`', function test( t )
152153
t.strictEqual( isnan( parts[1] ), true, 'returns NaN' );
153154
t.end();
154155
});
156+
157+
tape( 'the function supports providing an output array', function test( t ) {
158+
var parts;
159+
var out;
160+
161+
out = [ 0.0, 0.0 ];
162+
parts = modf( out, 3.14 );
163+
164+
t.strictEqual( parts, out, 'returns output array' );
165+
t.strictEqual( parts[ 0 ], 3.0, 'has expected first element' );
166+
t.strictEqual( parts[ 1 ], 0.14000000000000012, 'has expected second element' );
167+
168+
t.end();
169+
});
170+
171+
tape( 'the function supports providing an output typed array', function test( t ) {
172+
var parts;
173+
var out;
174+
175+
out = new Float64Array( 2 );
176+
parts = modf( out, 3.14 );
177+
178+
t.strictEqual( parts, out, 'returns output typed array' );
179+
t.strictEqual( parts[ 0 ], 3.0, 'has expected first element' );
180+
t.strictEqual( parts[ 1 ], 0.14000000000000012, 'has expected second element' );
181+
182+
t.end();
183+
});
184+
185+
tape( 'the function supports providing an output object', function test( t ) {
186+
var parts;
187+
var out;
188+
189+
out = {
190+
'length': 2,
191+
'0': 0.0,
192+
'1': 0.0
193+
};
194+
parts = modf( out, 3.14 );
195+
196+
t.strictEqual( parts, out, 'returns output object' );
197+
t.strictEqual( parts[ 0 ], 3.0, 'has expected first element' );
198+
t.strictEqual( parts[ 1 ], 0.14000000000000012, 'has expected second element' );
199+
200+
t.end();
201+
});

0 commit comments

Comments
 (0)