Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/node_modules/@stdlib/number/int64/ctor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ var w = x.lo;

### Static Methods

<a name="static-method-from"></a>

#### Int64.from( array )

Creates a new 64-bit signed integer from an array-like object containing a high and low word.
Expand All @@ -132,6 +134,8 @@ var x = Int64.from( [ 1234, 5678 ] );

#### Int64.of( high, low )

<a name="static-method-of"></a>

Creates a new 64-bit signed integer from a high and low word.

```javascript
Expand Down Expand Up @@ -189,7 +193,9 @@ var v = x.valueOf();

## Notes

- A 64-bit signed integer has a range of \[`-(2^63)`, `2^63-1`].
- A 64-bit signed integer has a range of `[-2^63, 2^63-1]`.
- The constructor accepts either a `number` or a `bigint` on the interval `[-2^63, 2^63-1]`.
- Passing a number argument is safe and exact for integers within `[-2^53, 2^53]`. For values exceeding `2^53` in magnitude, JavaScript numbers incur precision loss; provide a `bigint` argument or construct from words using [`Int64.of()`](#static-method-of) or [`Int64.from()`](#static-method-from).

</section>

Expand Down
29 changes: 10 additions & 19 deletions lib/node_modules/@stdlib/number/int64/ctor/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@
var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' );
var setReadOnlyAccessor = require( '@stdlib/utils/define-nonenumerable-read-only-accessor' );
var BigInt = require( '@stdlib/bigint/ctor' );
var Number = require( '@stdlib/number/ctor' );
var Uint32Array = require( '@stdlib/array/uint32' );
var join = require( '@stdlib/array/base/join' );
var UINT32_MAX = require( '@stdlib/constants/uint32/max' );
var MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' );
var MIN_SAFE_INTEGER = require( '@stdlib/constants/float64/min-safe-integer' );
var format = require( '@stdlib/string/format' );
var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' );
var bigint2words = require( '@stdlib/number/uint64/base/bigint2words' ).assign;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@impawstarlight Should we go ahead and add int64/base/bigint2words?

var number2words = require( '@stdlib/number/int64/base/number2words' ).assign;
var indices = require( './indices.js' );
var int2str = require( './to_string.js' );

Expand All @@ -48,6 +47,9 @@

var HAS_BIGINT = hasBigIntSupport();
var TWO_32 = 0x100000000; // 2^32
var TWO_63 = 0x8000000000000000; // 2^63
var STRIDE = indices.LOW - indices.HIGH;
var OFFSET = indices.HIGH;


// MAIN //
Expand All @@ -67,27 +69,16 @@
*/
function Int64( value ) {
var buffer;
var v;
if ( !( this instanceof Int64 ) ) {
throw new TypeError( 'invalid invocation. Constructor must be called with the `new` keyword.' );
}
buffer = new Uint32Array( 2 );
if ( isBigInt( value ) ) {
if ( BigInt.asIntN( 64, value ) !== value ) {
throw new TypeError( format( 'invalid argument. Must provide an integer on the interval [-(2^63), 2^63-1]. Value: `%s`.', value ) );
}
v = BigInt.asUintN( 64, value ); // Convert to unsigned to make it fixed-width
buffer[ indices.HIGH ] = Number( v >> BigInt( 32 ) );
buffer[ indices.LOW ] = Number( v & BigInt( UINT32_MAX ) );
} else if ( isInteger( value ) && isBetween( value, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER ) ) {
buffer[ indices.LOW ] = value >>> 0; // Truncate to 32-bit unsigned integer
if ( value >= 0 ) {
buffer[ indices.HIGH ] = ( value / TWO_32 ) >>> 0;
} else {
buffer[ indices.HIGH ] = ( ~( ( -value ) / TWO_32 ) + !buffer[ indices.LOW ] ) >>> 0; // 2's complement with carry from low word
}
if ( isBigInt( value ) && BigInt.asIntN( 64, value ) === value ) {
bigint2words( value, buffer, STRIDE, OFFSET );
} else if ( isInteger( value ) && isBetween( value, -TWO_63, TWO_63, 'closed', 'open' ) ) {
number2words( value, buffer, STRIDE, OFFSET );
} else {
throw new TypeError( format( 'invalid argument. Must provide an integer on the interval [-(2^53-1), 2^53-1]. Value: `%s`.', value ) );
throw new TypeError( format( 'invalid argument. Must provide an integer on the interval [-2^63, 2^63-1]. Value: `%s`.', value ) );
}
setReadOnly( this, '_buffer', buffer );
return this;
Expand Down Expand Up @@ -137,7 +128,7 @@
return v;
}

// TODO: consider supporting any iterable object

Check warning on line 131 in lib/node_modules/@stdlib/number/int64/ctor/lib/main.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unexpected 'todo' comment: 'TODO: consider supporting any iterable...'

if (
isInteger( words[ 0 ] ) &&
Expand All @@ -145,7 +136,7 @@
isBetween( words[ 0 ], 0, UINT32_MAX ) &&
isBetween( words[ 1 ], 0, UINT32_MAX )
) {
// TODO: consider whether we should support accessor arrays here

Check warning on line 139 in lib/node_modules/@stdlib/number/int64/ctor/lib/main.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unexpected 'todo' comment: 'TODO: consider whether we should support...'
v._buffer[ indices.HIGH ] = words[ 0 ]; // eslint-disable-line no-underscore-dangle
v._buffer[ indices.LOW ] = words[ 1 ]; // eslint-disable-line no-underscore-dangle
return v;
Expand Down Expand Up @@ -234,7 +225,7 @@
*
* @name hi
* @memberof Int64.prototype
* @type {uinteger32}

Check warning on line 228 in lib/node_modules/@stdlib/number/int64/ctor/lib/main.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unknown word: "uinteger"
* @returns {uinteger32} high word (32-bit unsigned integer)
*
* @example
Expand All @@ -252,7 +243,7 @@
*
* @name lo
* @memberof Int64.prototype
* @type {uinteger32}

Check warning on line 246 in lib/node_modules/@stdlib/number/int64/ctor/lib/main.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unknown word: "uinteger"
* @returns {uinteger32} low word (32-bit unsigned integer)
*
* @example
Expand Down Expand Up @@ -310,7 +301,7 @@
lo = ( ~lo + 1 ) >>> 0;
hi = ( ~hi + !lo ) >>> 0;
}
// TODO: Refactor to use `uint64/base/words2string` later

Check warning on line 304 in lib/node_modules/@stdlib/number/int64/ctor/lib/main.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unexpected 'todo' comment: 'TODO: Refactor to use...'
return sign + int2str( [ hi, lo ], rad );
});

Expand Down
42 changes: 34 additions & 8 deletions lib/node_modules/@stdlib/number/int64/ctor/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ var Int64 = require( './../lib' );
// VARIABLES //

var HAS_BIGINT = hasBigIntSupport();
var TWO_63 = 0x8000000000000000; // 2^63

var opts = {
'skip': !HAS_BIGINT
};


// TESTS //
Expand Down Expand Up @@ -94,8 +99,9 @@ tape( 'the constructor throws an error if provided an invalid/unsupported number
values = [
0.5,
-0.5,
MAX_SAFE_INTEGER + 1,
MIN_SAFE_INTEGER - 1
TWO_63,
TWO_63 + 2048,
-TWO_63 - 2048
];
for ( i = 0; i < values.length; i++ ) {
t.throws( badValue( values[i] ), TypeError, format( 'throws an error when provided %s', values[i] ) );
Expand All @@ -110,15 +116,10 @@ tape( 'the constructor throws an error if provided an invalid/unsupported number
}
});

tape( 'the constructor throws an error if provided an invalid/unsupported BigInt', function test( t ) {
tape( 'the constructor throws an error if provided an invalid/unsupported BigInt', opts, function test( t ) {
var values;
var i;

if ( !HAS_BIGINT ) {
t.end();
return;
}

values = [
BigInt( '0x8000000000000000' ), // 2^63
-BigInt( '0x80000000000000001' ) // -(2^63) - 1
Expand Down Expand Up @@ -164,6 +165,31 @@ tape( 'the constructor returns a 64-bit signed integer', function test( t ) {
t.strictEqual( x.hi, 4292870144, 'returns expected value' );
t.strictEqual( x.lo, 1, 'returns expected value' );

x = new Int64( MAX_SAFE_INTEGER + 1 );
t.ok( x instanceof Int64, 'returns expected value' );
t.strictEqual( x.hi, 2097152, 'returns expected value' );
t.strictEqual( x.lo, 0, 'returns expected value' );

x = new Int64( MIN_SAFE_INTEGER - 1 );
t.ok( x instanceof Int64, 'returns expected value' );
t.strictEqual( x.hi, 4292870144, 'returns expected value' );
t.strictEqual( x.lo, 0, 'returns expected value' );

x = new Int64( TWO_63 - 1024 ); // Largest integer value less than 2^63 exactly representable as a double
t.ok( x instanceof Int64, 'returns expected value' );
t.strictEqual( x.hi, 2147483647, 'returns expected value' );
t.strictEqual( x.lo, 4294966272, 'returns expected value' );

x = new Int64( -TWO_63 ); // Smallest integer value on the interval [-(2^63), 2^63-1]
t.ok( x instanceof Int64, 'returns expected value' );
t.strictEqual( x.hi, 2147483648, 'returns expected value' );
t.strictEqual( x.lo, 0, 'returns expected value' );

x = new Int64( -TWO_63 + 1024 );
t.ok( x instanceof Int64, 'returns expected value' );
t.strictEqual( x.hi, 2147483648, 'returns expected value' );
t.strictEqual( x.lo, 1024, 'returns expected value' );

if ( HAS_BIGINT ) {
x = new Int64( BigInt( 0 ) );
t.ok( x instanceof Int64, 'returns expected value' );
Expand Down
22 changes: 18 additions & 4 deletions lib/node_modules/@stdlib/number/int64/ctor/test/test.to_string.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,21 @@
// MODULES //

var tape = require( 'tape' );
var hasBigIntSupport = require( '@stdlib/assert/has-bigint-support' );
var BigInt = require( '@stdlib/bigint/ctor' );
var MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' );
var UINT32_MAX = require( '@stdlib/constants/uint32/max' );
var Int64 = require( './../lib' );


// VARIABLES //

var TWO_63 = 0x8000000000000000; // 2^63
var opts = {
'skip': !hasBigIntSupport()
};


// TESTS //

tape( 'main export is a function', function test( t ) {
Expand All @@ -49,7 +59,7 @@ tape( 'the constructor returns an instance having a `toString` method for serial
t.end();
});

tape( 'the method accepts a radix parameter for serializing an instance as a string in bases 2 through 36', function test( t ) {
tape( 'the method accepts a radix parameter for serializing an instance as a string in bases 2 through 36', opts, function test( t ) {
var values;
var radix;
var i;
Expand All @@ -71,21 +81,25 @@ tape( 'the method accepts a radix parameter for serializing an instance as a str
UINT32_MAX,
UINT32_MAX + 1,
MAX_SAFE_INTEGER - 1,
MAX_SAFE_INTEGER
MAX_SAFE_INTEGER,
MAX_SAFE_INTEGER + 1,
TWO_63 - 1024 // Largest integer value less than 2^63 exactly representable as a double
];

for ( i = 0; i < values.length; i++ ) {
z = values[i];
z = BigInt( values[i] );
x = new Int64( z );

for ( radix = 2; radix <= 36; radix++ ) {
t.strictEqual( x.toString( radix ), z.toString( radix ), 'returns expected value' );
}
}

values.push( TWO_63 ); // when negated, corresponds to -(2^63)

// Negative values:
for ( i = 0; i < values.length; i++ ) {
z = -values[i];
z = -BigInt( values[i] );
x = new Int64( z );

for ( radix = 2; radix <= 36; radix++ ) {
Expand Down
Loading