diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/README.md b/lib/node_modules/@stdlib/number/uint64/ctor/README.md index becfea87b0d7..f2c7e9b93089 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/README.md +++ b/lib/node_modules/@stdlib/number/uint64/ctor/README.md @@ -121,6 +121,8 @@ var w = x.lo; ### Static Methods + + #### Uint64.from( array ) Creates a new 64-bit unsigned integer from an array-like object containing a high and low word. @@ -130,6 +132,8 @@ var x = Uint64.from( [ 1234, 5678 ] ); // returns ``` + + #### Uint64.of( high, low ) Creates a new 64-bit unsigned integer from a high and low word. @@ -190,6 +194,8 @@ var v = x.valueOf(); ## Notes - A 64-bit unsigned integer has a range of \[`0`, `2^64-1`]. +- The constructor accepts either a `number` or a `bigint` on the interval `[0, 2^64-1]`. +- Passing a number argument is safe and exact for integers within \[`0`, `2^53`]. For values exceeding `2^53`, JavaScript numbers incur precision loss; provide a `bigint` argument or construct from words using [`Uint64.of()`](#static-method-of) or [`Uint64.from()`](#static-method-from). diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js index 6e5579a28a06..438a9d0efb46 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -32,13 +32,13 @@ var isBetween = require( '@stdlib/assert/is-between' ); 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 format = require( '@stdlib/string/format' ); var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); +var bigint2words = require( '@stdlib/number/uint64/base/bigint2words' ).assign; +var number2words = require( '@stdlib/number/uint64/base/number2words' ).assign; var indices = require( './indices.js' ); var int2str = require( './to_string.js' ); @@ -47,6 +47,9 @@ var int2str = require( './to_string.js' ); var HAS_BIGINT = hasBigIntSupport(); var TWO_32 = 0x100000000; // 2^32 +var TWO_64 = 0x10000000000000000; // 2^64 +var STRIDE = indices.LOW - indices.HIGH; +var OFFSET = indices.HIGH; // MAIN // @@ -66,23 +69,16 @@ var TWO_32 = 0x100000000; // 2^32 */ function Uint64( value ) { var buffer; - var v; if ( !( this instanceof Uint64 ) ) { throw new TypeError( 'invalid invocation. Constructor must be called with the `new` keyword.' ); } buffer = new Uint32Array( 2 ); - if ( isBigInt( value ) ) { - v = BigInt.asUintN( 64, value ); - if ( v !== value ) { - throw new TypeError( format( 'invalid argument. Must provide an integer on the interval [0, 2^64-1]. Value: `%s`.', value ) ); - } - buffer[ indices.HIGH ] = Number( v >> BigInt( 32 ) ); - buffer[ indices.LOW ] = Number( v & BigInt( UINT32_MAX ) ); - } else if ( isInteger( value ) && isBetween( value, 0, MAX_SAFE_INTEGER ) ) { - buffer[ indices.HIGH ] = ( value / TWO_32 ) >>> 0; - buffer[ indices.LOW ] = value >>> 0; + if ( isBigInt( value ) && BigInt.asUintN( 64, value ) === value ) { + bigint2words( value, buffer, STRIDE, OFFSET ); + } else if ( isInteger( value ) && isBetween( value, 0, TWO_64, 'closed', 'open' ) ) { + number2words( value, buffer, STRIDE, OFFSET ); } else { - throw new TypeError( format( 'invalid argument. Must provide an integer on the interval [0, 2^53-1]. Value: `%s`.', value ) ); + throw new TypeError( format( 'invalid argument. Must provide an integer on the interval [0, 2^64-1]. Value: `%s`.', value ) ); } setReadOnly( this, '_buffer', buffer ); return this; diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js index f9ef99f49d82..647a67909c9c 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -35,6 +35,7 @@ var Uint64 = require( './../lib' ); // VARIABLES // var HAS_BIGINT = hasBigIntSupport(); +var TWO_64 = 0x10000000000000000; // 2^64 // TESTS // @@ -93,7 +94,8 @@ tape( 'the constructor throws an error if provided an invalid/unsupported number values = [ -1, 0.5, - 1 + MAX_SAFE_INTEGER + TWO_64, + TWO_64 + 4096 // Smallest integer greater than 2^64 exactly representable as a double ]; for ( i = 0; i < values.length; i++ ) { t.throws( badValue( values[i] ), TypeError, format( 'throws an error when provided %s', values[i] ) ); @@ -152,6 +154,16 @@ tape( 'the constructor returns a 64-bit unsigned integer', function test( t ) { t.strictEqual( x.hi, 2097151, 'returns expected value' ); t.strictEqual( x.lo, 4294967295, 'returns expected value' ); + x = new Uint64( MAX_SAFE_INTEGER + 1 ); + t.ok( x instanceof Uint64, 'returns expected value' ); + t.strictEqual( x.hi, 2097152, 'returns expected value' ); + t.strictEqual( x.lo, 0, 'returns expected value' ); + + x = new Uint64( TWO_64 - 2048 ); // Largest integer less than 2^64 exactly representable as a double + t.ok( x instanceof Uint64, 'returns expected value' ); + t.strictEqual( x.hi, 4294967295, 'returns expected value' ); + t.strictEqual( x.lo, 4294965248, 'returns expected value' ); + if ( HAS_BIGINT ) { x = new Uint64( BigInt( 0 ) ); t.ok( x instanceof Uint64, 'returns expected value' ); diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.to_string.js b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.to_string.js index 1b43a01a50b4..6689c9f948e3 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.to_string.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.to_string.js @@ -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 Uint64 = require( './../lib' ); +// VARIABLES // + +var TWO_64 = 0x10000000000000000; // 2^64 +var opts = { + 'skip': !hasBigIntSupport() +}; + + // TESTS // tape( 'main export is a function', function test( t ) { @@ -46,7 +56,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; @@ -68,11 +78,13 @@ 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_64 - 2048 // Maximum integer value less than 2^64 that can be stored in a 64-bit float ]; for ( i = 0; i < values.length; i++ ) { - z = values[i]; + z = BigInt( values[i] ); x = new Uint64( z ); for ( radix = 2; radix <= 36; radix++ ) {