From 26f9a3ffac355a8cd2f74bf8f948b420a3933aa7 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 02:52:41 +0600 Subject: [PATCH 01/29] chore: copy main.js from `number/float16/ctor` --- .../@stdlib/number/uint64/ctor/lib/main.js | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js new file mode 100644 index 000000000000..cf44b6b23c6e --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -0,0 +1,186 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; +var setEnumerableReadOnly = require( '@stdlib/utils/define-read-only-property' ); +var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var float64ToFloat16 = require( '@stdlib/number/float64/base/to-float16' ); +var format = require( '@stdlib/string/format' ); +var hasToPrimitiveSymbolSupport = require( '@stdlib/assert/has-to-primitive-symbol-support' ); // eslint-disable-line id-length +var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); +var toStr = require( './tostring.js' ); +var toJSON = require( './tojson.js' ); +var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redeclare + + +// MAIN // + +/** +* 16-bit half-precision floating-point number constructor. +* +* @constructor +* @param {number} value - numeric value +* @throws {TypeError} must invoke using the `new` keyword +* @throws {TypeError} value must be a number +* @returns {Float16} 16-bit half-precision floating-point number +* +* @example +* var x = new Float16( 5.0 ); +* // returns +*/ +function Float16( value ) { + if ( !( this instanceof Float16 ) ) { + throw new TypeError( 'invalid invocation. Constructor must be called with the `new` keyword.' ); + } + if ( !isNumber( value ) ) { + throw new TypeError( format( 'invalid argument. Must provide a number. Value: `%s`.', value ) ); + } + setEnumerableReadOnly( this, 'value', float64ToFloat16( value ) ); + return this; +} + +/** +* Constructor name. +* +* @name name +* @memberof Float16 +* @readonly +* @type {string} +* @default 'Float16' +* +* @example +* var name = Float16.name; +* // returns 'Float16' +*/ +setReadOnly( Float16, 'name', 'Float16' ); + +/** +* Size (in bytes) of the underlying value. +* +* @name BYTES_PER_ELEMENT +* @memberof Float16 +* @type {integer} +* @returns {integer} size in bytes +* +* @example +* var nbytes = Float16.BYTES_PER_ELEMENT; +* // returns 2 +*/ +setReadOnly( Float16, 'BYTES_PER_ELEMENT', 2 ); + +/** +* Size (in bytes) of the underlying value. +* +* @name BYTES_PER_ELEMENT +* @memberof Float16.prototype +* @type {integer} +* @returns {integer} size in bytes +* +* @example +* var x = new Float16( 5.0 ); +* +* var nbytes = x.BYTES_PER_ELEMENT; +* // returns 2 +*/ +setReadOnly( Float16.prototype, 'BYTES_PER_ELEMENT', 2 ); + +/** +* Serializes a half-precision floating-point number as a string. +* +* @name toString +* @memberof Float16.prototype +* @type {Function} +* @returns {string} serialized half-precision floating-point number +* +* @example +* var x = new Float16( 5.0 ); +* +* var str = x.toString(); +* // returns '5' +*/ +setReadOnly( Float16.prototype, 'toString', toStr ); + +/** +* Serializes a half-precision floating-point number as a JSON object. +* +* ## Notes +* +* - `JSON.stringify()` implicitly calls this method when stringifying a `Float16` instance. +* +* @name toJSON +* @memberof Float16.prototype +* @type {Function} +* @returns {Object} serialized half-precision floating-point number +* +* @example +* var x = new Float16( 5.0 ); +* +* var obj = x.toJSON(); +* // returns { 'type': 'Float16', 'value': 5.0 } +*/ +setReadOnly( Float16.prototype, 'toJSON', toJSON ); + +/** +* Converts a half-precision floating-point number to a primitive value. +* +* @name valueOf +* @memberof Float16.prototype +* @type {Function} +* @returns {number} primitive value +* +* @example +* var x = new Float16( 5.0 ); +* +* var v = x.valueOf(); +* // returns 5.0 +*/ +setReadOnly( Float16.prototype, 'valueOf', valueOf ); + +/** +* Returns the primitive value of a half-precision floating-point number. +* +* @name toPrimitive +* @memberof Float16.prototype +* @type {Function} +* @param {string} hint - conversion hint +* @returns {number} primitive value +* +* @example +* var hasSymbol = require( '@stdlib/assert/has-to-primitive-symbol-support' ); +* var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); +* +* var x = new Float16( 5.0 ); +* +* var v; +* if ( hasSymbol() ) { +* v = x[ ToPrimitiveSymbol ]( 'number' ); +* // returns 5.0 +* } +*/ +if ( hasToPrimitiveSymbolSupport() ) { + setReadOnly( Float16.prototype, ToPrimitiveSymbol, valueOf ); +} + + +// EXPORTS // + +module.exports = Float16; From c9b0b08e1c34e8b71048f9c3dbd83c198e320d8f Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 03:19:49 +0600 Subject: [PATCH 02/29] chore: rename float16 stuff to uint64 --- .../@stdlib/number/uint64/ctor/lib/main.js | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) 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 cf44b6b23c6e..cf04a4facf68 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; var setEnumerableReadOnly = require( '@stdlib/utils/define-read-only-property' ); var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); -var float64ToFloat16 = require( '@stdlib/number/float64/base/to-float16' ); var format = require( '@stdlib/string/format' ); var hasToPrimitiveSymbolSupport = require( '@stdlib/assert/has-to-primitive-symbol-support' ); // eslint-disable-line id-length var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); @@ -35,26 +34,27 @@ var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redecl // MAIN // /** -* 16-bit half-precision floating-point number constructor. +* Unsigned 64-bit integer constructor. * * @constructor -* @param {number} value - numeric value +* @param {number|string|number[]|Uint32Array|BigInt} value - numeric value or high low words or BigInt // TODO: Which ones should we keep? * @throws {TypeError} must invoke using the `new` keyword -* @throws {TypeError} value must be a number -* @returns {Float16} 16-bit half-precision floating-point number +* @throws {TypeError} value must be a number or bla bla bla // TODO: update after review +* @returns {Uint64} Unsigned 64-bit integer * -* @example -* var x = new Float16( 5.0 ); -* // returns +* @example // TODO: add more example +* var x = new Uint64( 5 ); +* // returns */ -function Float16( value ) { - if ( !( this instanceof Float16 ) ) { +function Uint64( value ) { + if ( !( this instanceof Uint64 ) ) { throw new TypeError( 'invalid invocation. Constructor must be called with the `new` keyword.' ); } + // TODO: Implement initialization logic with all supported parameter types if ( !isNumber( value ) ) { throw new TypeError( format( 'invalid argument. Must provide a number. Value: `%s`.', value ) ); } - setEnumerableReadOnly( this, 'value', float64ToFloat16( value ) ); + // setEnumerableReadOnly( this, 'value', float64ToFloat16( value ) ); return this; } @@ -62,104 +62,104 @@ function Float16( value ) { * Constructor name. * * @name name -* @memberof Float16 +* @memberof Uint64 * @readonly * @type {string} -* @default 'Float16' +* @default 'Uint64' * * @example -* var name = Float16.name; -* // returns 'Float16' +* var name = Uint64.name; +* // returns 'Uint64' */ -setReadOnly( Float16, 'name', 'Float16' ); +setReadOnly( Uint64, 'name', 'Uint64' ); /** * Size (in bytes) of the underlying value. * * @name BYTES_PER_ELEMENT -* @memberof Float16 +* @memberof Uint64 * @type {integer} * @returns {integer} size in bytes * * @example -* var nbytes = Float16.BYTES_PER_ELEMENT; -* // returns 2 +* var nbytes = Uint64.BYTES_PER_ELEMENT; +* // returns 8 */ -setReadOnly( Float16, 'BYTES_PER_ELEMENT', 2 ); +setReadOnly( Uint64, 'BYTES_PER_ELEMENT', 8 ); /** * Size (in bytes) of the underlying value. * * @name BYTES_PER_ELEMENT -* @memberof Float16.prototype +* @memberof Uint64.prototype * @type {integer} * @returns {integer} size in bytes * * @example -* var x = new Float16( 5.0 ); +* var x = new Uint64( 5 ); * * var nbytes = x.BYTES_PER_ELEMENT; -* // returns 2 +* // returns 8 */ -setReadOnly( Float16.prototype, 'BYTES_PER_ELEMENT', 2 ); +setReadOnly( Uint64.prototype, 'BYTES_PER_ELEMENT', 8 ); /** -* Serializes a half-precision floating-point number as a string. +* Serializes an unsigned 64-bit integer number as a string. * * @name toString -* @memberof Float16.prototype +* @memberof Uint64.prototype * @type {Function} -* @returns {string} serialized half-precision floating-point number +* @returns {string} serialized unsigned 64-bit integer number * * @example -* var x = new Float16( 5.0 ); +* var x = new Uint64( 5 ); * * var str = x.toString(); * // returns '5' */ -setReadOnly( Float16.prototype, 'toString', toStr ); +setReadOnly( Uint64.prototype, 'toString', toStr ); /** -* Serializes a half-precision floating-point number as a JSON object. +* Serializes an unsigned 64-bit integer number as a JSON object. * * ## Notes * -* - `JSON.stringify()` implicitly calls this method when stringifying a `Float16` instance. +* - `JSON.stringify()` implicitly calls this method when stringifying a `Uint64` instance. * * @name toJSON -* @memberof Float16.prototype +* @memberof Uint64.prototype * @type {Function} -* @returns {Object} serialized half-precision floating-point number +* @returns {Object} serialized unsigned 64-bit integer number * * @example -* var x = new Float16( 5.0 ); +* var x = new Uint64( 5 ); * * var obj = x.toJSON(); -* // returns { 'type': 'Float16', 'value': 5.0 } +* // returns { 'type': 'Uint64', 'value': '5' } // TODO: value as string for best compatibility? */ -setReadOnly( Float16.prototype, 'toJSON', toJSON ); +setReadOnly( Uint64.prototype, 'toJSON', toJSON ); /** -* Converts a half-precision floating-point number to a primitive value. +* Converts an unsigned 64-bit integer number to a primitive value. * * @name valueOf -* @memberof Float16.prototype +* @memberof Uint64.prototype * @type {Function} * @returns {number} primitive value * * @example -* var x = new Float16( 5.0 ); +* var x = new Uint64( 5 ); * * var v = x.valueOf(); * // returns 5.0 */ -setReadOnly( Float16.prototype, 'valueOf', valueOf ); +setReadOnly( Uint64.prototype, 'valueOf', valueOf ); /** -* Returns the primitive value of a half-precision floating-point number. +* Returns the primitive value of an unsigned 64-bit integer number. * * @name toPrimitive -* @memberof Float16.prototype +* @memberof Uint64.prototype * @type {Function} * @param {string} hint - conversion hint * @returns {number} primitive value @@ -168,7 +168,7 @@ setReadOnly( Float16.prototype, 'valueOf', valueOf ); * var hasSymbol = require( '@stdlib/assert/has-to-primitive-symbol-support' ); * var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); * -* var x = new Float16( 5.0 ); +* var x = new Uint64( 5 ); * * var v; * if ( hasSymbol() ) { @@ -177,10 +177,10 @@ setReadOnly( Float16.prototype, 'valueOf', valueOf ); * } */ if ( hasToPrimitiveSymbolSupport() ) { - setReadOnly( Float16.prototype, ToPrimitiveSymbol, valueOf ); + setReadOnly( Uint64.prototype, ToPrimitiveSymbol, valueOf ); } // EXPORTS // -module.exports = Float16; +module.exports = Uint64; From dd5a4d668198891fe14ff94f7081a28f546a38a1 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 07:03:02 +0600 Subject: [PATCH 03/29] feat: add asBigUint64 function to truncate BigInt to unsigned 64-bit integer --- .../number/uint64/ctor/lib/asbiguint64.js | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/asbiguint64.js diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/asbiguint64.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/asbiguint64.js new file mode 100644 index 000000000000..f402056b722f --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/asbiguint64.js @@ -0,0 +1,46 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var BigInt = require( '@stdlib/bigint/ctor' ); + + +// MAIN // + +/** +* Truncates a BigInt value to 64 least significant bits as an unsigned integer. +* +* @constructor +* @param {BigInt} value - BigInt value to truncate +* @returns {BigInt} Unsigned 64-bit BigInt +* +* @example +* var x = asBigUint64( 0x0123456789abcdef0000n ).toString(16); +* // returns '456789abcdef0000' +*/ +function asBigUint64( value ) { + return BigInt.asUintN( 64, value ); +} + + +// EXPORTS // + +module.exports = asBigUint64; From 03e0b6a63f5bd86746fdd18429133ef819260b6b Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 07:04:51 +0600 Subject: [PATCH 04/29] feat: add toString, toJSON, and valueOf --- .../@stdlib/number/uint64/ctor/lib/tojson.js | 43 +++++++++++++++++ .../number/uint64/ctor/lib/tostring.js | 47 +++++++++++++++++++ .../@stdlib/number/uint64/ctor/lib/valueof.js | 47 +++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js new file mode 100644 index 000000000000..5ee068e3caf6 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js @@ -0,0 +1,43 @@ +/* eslint-disable no-invalid-this */ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Serializes an unsigned 64-bit integer as a JSON object. +* +* @private +* @returns {Object} JSON representation +*/ +function toJSON() { + var out = {}; + out.type = 'Uint64'; + if ( typeof this.value === 'bigint' ) { + out.value = this.value.toString(); + } + else { + out.value = [ this.value[ 0 ], this.value[ 1 ] ]; + } + return out; +} + + +// EXPORTS // + +module.exports = toJSON; diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js new file mode 100644 index 000000000000..3a657433f456 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js @@ -0,0 +1,47 @@ +/* eslint-disable no-invalid-this */ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +/** +* Serializes an unsigned 64-bit integer as a string. +* +* @private +* @param {number} base - radix +* @returns {string} serialized unsigned 64-bit integer +*/ +function toString( base ) { // eslint-disable-line stdlib/no-redeclare + // eslint-disable-next-line no-undefined + if ( base === undefined ) { + base = 10; + } + if ( typeof this.value === 'bigint' ) { + return this.value.toString( base ); + } + + // TODO: implement double word base conversion + return '?'; +} + + +// EXPORTS // + +module.exports = toString; diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js new file mode 100644 index 000000000000..87f538b63f2f --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js @@ -0,0 +1,47 @@ +/* eslint-disable no-invalid-this */ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var Number = require( '@stdlib/number/ctor' ); + + +// MAIN // + +/** +* Converts an unsigned 64-bit integer to a primitive value. +* +* @private +* @returns {number} primitive value +*/ +function valueOf() { // eslint-disable-line stdlib/no-redeclare + if ( typeof this.value === 'bigint' ) { + return Number( this.value ); + } + + // TODO: implement conversion to number + return -1; +} + + +// EXPORTS // + +module.exports = valueOf; From b27d0e12761118467af19ab3ab4f197145017914 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 07:18:45 +0600 Subject: [PATCH 05/29] feat: implement Uint64 constructor with support for BigInt, Uint32Array, array, and string inputs --- .../@stdlib/number/uint64/ctor/lib/main.js | 84 +++++++++++++++++-- 1 file changed, 76 insertions(+), 8 deletions(-) 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 cf04a4facf68..44c67c3df3f9 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -20,12 +20,20 @@ // MODULES // +var BigInt = require( '@stdlib/bigint/ctor' ); +var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); +var Uint32Array = require( '@stdlib/array/uint32' ); +var format = require( '@stdlib/string/format' ); +var hasBigIntSupport = require( '@stdlib/assert/has-bigint-support' ); +var hasToPrimitiveSymbolSupport = require( '@stdlib/assert/has-to-primitive-symbol-support' ); // eslint-disable-line id-length +var isArray = require( '@stdlib/assert/is-array' ); +var isBigInt = require( '@stdlib/assert/is-bigint' ); var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; +var isString = require( '@stdlib/assert/is-string' ); +var isUint32Array = require( '@stdlib/assert/is-uint32array' ); var setEnumerableReadOnly = require( '@stdlib/utils/define-read-only-property' ); var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); -var format = require( '@stdlib/string/format' ); -var hasToPrimitiveSymbolSupport = require( '@stdlib/assert/has-to-primitive-symbol-support' ); // eslint-disable-line id-length -var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); +var asBigUint64 = require( './asbiguint64.js' ); var toStr = require( './tostring.js' ); var toJSON = require( './tojson.js' ); var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redeclare @@ -47,14 +55,74 @@ var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redecl * // returns */ function Uint64( value ) { + var hasBigInt = hasBigIntSupport(); if ( !( this instanceof Uint64 ) ) { throw new TypeError( 'invalid invocation. Constructor must be called with the `new` keyword.' ); } - // TODO: Implement initialization logic with all supported parameter types - if ( !isNumber( value ) ) { - throw new TypeError( format( 'invalid argument. Must provide a number. Value: `%s`.', value ) ); + + if ( isBigInt( value ) ) { + setEnumerableReadOnly( this, 'value', asBigUint64( value ) ); + } + else if ( isUint32Array( value ) ) { + if ( value.length === 2 ) { + if ( hasBigInt ) { + setEnumerableReadOnly( this, 'value', ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ) ); + } + else { + setEnumerableReadOnly( this, 'value', value ); + } + } + else { + throw new TypeError( format( 'invalid argument. Provided Uint32Array must have a length of 2. Value: `%s`.', value ) ); + } + } + else if ( isArray( value ) ) { + if ( value.length === 2 ) { + if ( typeof value[ 0 ] === 'number' && typeof value[ 1 ] === 'number' ) { + value[ 0 ] >>>= 0; + value[ 1 ] >>>= 0; + if ( hasBigInt ) { + setEnumerableReadOnly( this, 'value', ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ) ); + } + else { + setEnumerableReadOnly( this, 'value', new Uint32Array( value ) ); + } + } + else { + throw new TypeError( format( 'invalid argument. Provided array must contain only elements of type number. Value: `%s`.', value ) ); + } + } + else { + throw new TypeError( format( 'invalid argument. Provided array must have a length of 2. Value: `%s`.', value ) ); + } + } + else if ( isString( value ) ) { + if ( hasBigInt ) { + try { + setEnumerableReadOnly( this, 'value', asBigUint64( BigInt( value ) ) ); + } + // eslint-disable-next-line no-unused-vars + catch ( error ) { + throw new TypeError( format( 'invalid argument. Could not convert string to BigInt. Value: `%s`.', value ) ); + } + } + else { + // TODO: decompose into high low + setEnumerableReadOnly( this, 'value', new Uint32Array( [ 0, 0 ] ) ); + } + } + else if ( isNumber( value ) ) { + value >>>= 0; + if ( hasBigInt ) { + setEnumerableReadOnly( this, 'value', asBigUint64( BigInt( value ) ) ); + } + else { + setEnumerableReadOnly( this, 'value', new Uint32Array( [ 0, value ] ) ); + } + } + else { + throw new TypeError( format( 'invalid argument. Must provide a number or string or number[] or Uint32Array or BigInt. Value: `%s`.', value ) ); } - // setEnumerableReadOnly( this, 'value', float64ToFloat16( value ) ); return this; } @@ -135,7 +203,7 @@ setReadOnly( Uint64.prototype, 'toString', toStr ); * var x = new Uint64( 5 ); * * var obj = x.toJSON(); -* // returns { 'type': 'Uint64', 'value': '5' } // TODO: value as string for best compatibility? +* // returns { 'type': 'Uint64', 'value': '5' } */ setReadOnly( Uint64.prototype, 'toJSON', toJSON ); From 7c40edd0f0afa7b2dbf72efa7e6ed1216285e9d8 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 08:06:55 +0600 Subject: [PATCH 06/29] feat: add README and package.json --- .../@stdlib/number/uint64/ctor/README.md | 232 ++++++++++++++++++ .../number/uint64/ctor/lib/asbiguint64.js | 2 +- .../@stdlib/number/uint64/ctor/lib/main.js | 6 +- .../@stdlib/number/uint64/ctor/lib/tojson.js | 1 + .../@stdlib/number/uint64/ctor/package.json | 67 +++++ 5 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/README.md create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/package.json diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/README.md b/lib/node_modules/@stdlib/number/uint64/ctor/README.md new file mode 100644 index 000000000000..e65638f13020 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/README.md @@ -0,0 +1,232 @@ + + +# Uint64 + +> Unsigned 64-bit integer. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var Uint64 = require( '@stdlib/number/uint64/ctor' ); +``` + +#### Uint64( value ) + +Unsigned 64-bit integer constructor. + +```javascript +var x = new Uint64( 5 ); +// returns +``` + +* * * + +## Properties + +#### Uint64.name + +Static property returning the constructor name. + +```javascript +var str = Uint64.name; +// returns 'Uint64' +``` + +#### Uint64.BYTES_PER_ELEMENT + +Size (in bytes) of the underlying value. + +```javascript +var nbytes = Uint64.BYTES_PER_ELEMENT; +// returns 8 +``` + +#### Uint64.prototype.BYTES_PER_ELEMENT + +Size (in bytes) of the underlying value. + +```javascript +var x = new Uint64( 5 ); + +var nbytes = x.BYTES_PER_ELEMENT; +// returns 8 +``` + +### Instance + +A `Uint64` instance has the following properties... + +#### value + +A **read-only** property returning the underlying value as a number. + +```javascript +var x = new Uint64( 5 ); + +var v = x.value; +// returns 5.0 +``` + +* * * + +## Methods + +### Accessor Methods + +These methods do **not** mutate a `Uint64` instance and, instead return an unsigned 64-bit integer representation. + +#### Uint64.prototype.toString() + +Returns a string representation of a `Uint64` instance. + +```javascript +var x = new Uint64( 5.0 ); +var str = x.toString(); +// returns '5' +``` + +#### Uint64.prototype.toJSON() + +Returns a [JSON][json] representation of a `Uint64` instance. [`JSON.stringify()`][mdn-json-stringify] implicitly calls this method when stringifying a `Uint64` instance. + +```javascript +var x = new Uint64( 5.0 ); + +var o = x.toJSON(); +/* + { + "type": "Uint64", + "value": '5' + } +*/ +``` + +To [revive][mdn-json-parse] a `Uint64` number from a [JSON][json] `string`, see [@stdlib/number/uint64/reviver][@stdlib/number/uint64/reviver]. + +#### Uint64.prototype.valueOf() + +Converts a `Uint64` instance to a primitive value. + +```javascript +var x = new Uint64( 5.0 ); +var v = x.valueOf(); +// returns 5.0 +``` + +
+ + + +* * * + + + +
+ +## Notes + +- The underlying value is stored as an unsigned 64-bit integer. +- An unsigned 64-bit integer has a range of [`0`, `2^64-1`]. + +
+ + + +* * * + + + +
+ +## Examples + + + +```javascript +var Uint64 = require( '@stdlib/number/uint64/ctor' ); + +var x = new Uint64( 1234 ); + +console.log( 'type: %s', typeof x ); +// => 'type: object' + +console.log( 'str: %s', x ); +// => 'str: 1234' + +console.log( 'value: %d', x.value ); +// => 'value: 1234' + +console.log( 'JSON: %s', JSON.stringify( x ) ); +// => 'JSON: {"type":"Uint64","value":"1234"}' +``` + +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/asbiguint64.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/asbiguint64.js index f402056b722f..5fcce08cda6d 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/asbiguint64.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/asbiguint64.js @@ -28,7 +28,7 @@ var BigInt = require( '@stdlib/bigint/ctor' ); /** * Truncates a BigInt value to 64 least significant bits as an unsigned integer. * -* @constructor +* @private * @param {BigInt} value - BigInt value to truncate * @returns {BigInt} Unsigned 64-bit BigInt * 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 44c67c3df3f9..cad82d80950b 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -45,7 +45,7 @@ var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redecl * Unsigned 64-bit integer constructor. * * @constructor -* @param {number|string|number[]|Uint32Array|BigInt} value - numeric value or high low words or BigInt // TODO: Which ones should we keep? +* @param {number|string|number[]|Uint32Array|BigInt} value - numeric value or high low words or BigInt // TODO: Which ones should we keep and discard? * @throws {TypeError} must invoke using the `new` keyword * @throws {TypeError} value must be a number or bla bla bla // TODO: update after review * @returns {Uint64} Unsigned 64-bit integer @@ -60,6 +60,10 @@ function Uint64( value ) { throw new TypeError( 'invalid invocation. Constructor must be called with the `new` keyword.' ); } + // TODO: current implementation uses either BigInt or Uint32Array for the internal representation + // Are there other better alternative instead of Uint32Array? How is plain old number array? + // Or an object with high and low props? + if ( isBigInt( value ) ) { setEnumerableReadOnly( this, 'value', asBigUint64( value ) ); } diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js index 5ee068e3caf6..fd8df087dcbd 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js @@ -34,6 +34,7 @@ function toJSON() { else { out.value = [ this.value[ 0 ], this.value[ 1 ] ]; } + // TODO: is it bad to have 2 different kind of json representation? return out; } diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/package.json b/lib/node_modules/@stdlib/number/uint64/ctor/package.json new file mode 100644 index 000000000000..56db7dbfb7fe --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/package.json @@ -0,0 +1,67 @@ +{ + "name": "@stdlib/number/uint64/ctor", + "version": "0.0.0", + "description": "Unsigned 64-bit integer.", + "license": "Apache-2.0", + "author": { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + }, + "contributors": [ + { + "name": "The Stdlib Authors", + "url": "https://github.com/stdlib-js/stdlib/graphs/contributors" + } + ], + "main": "./lib", + "directories": { + "benchmark": "./benchmark", + "doc": "./docs", + "example": "./examples", + "include": "./include", + "lib": "./lib", + "src": "./src", + "test": "./test" + }, + "types": "./docs/types", + "scripts": {}, + "homepage": "https://github.com/stdlib-js/stdlib", + "repository": { + "type": "git", + "url": "git://github.com/stdlib-js/stdlib.git" + }, + "bugs": { + "url": "https://github.com/stdlib-js/stdlib/issues" + }, + "dependencies": {}, + "devDependencies": {}, + "engines": { + "node": ">=0.10.0", + "npm": ">2.7.0" + }, + "os": [ + "aix", + "darwin", + "freebsd", + "linux", + "macos", + "openbsd", + "sunos", + "win32", + "windows" + ], + "keywords": [ + "stdlib", + "stdtypes", + "types", + "data", + "structure", + "constructor", + "ctor", + "uint64", + "unsigned", + "64-bit", + "integer", + "int" + ] +} From 8ecf4288a36e742b64be4d2a335f73cec40eb1c7 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 08:11:11 +0600 Subject: [PATCH 07/29] feat: add index.js --- .../@stdlib/number/uint64/ctor/lib/index.js | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js new file mode 100644 index 000000000000..6eb0c1ad8292 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js @@ -0,0 +1,40 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +/** +* Unsigned 64-bit integer constructor. +* +* @module @stdlib/number/uint64/ctor +* +* @example +* var Uint64 = require( '@stdlib/number/uint64/ctor' ); +* +* var x = new Uint64( 5.0 ); +* // returns +*/ + +// MODULES // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; From 64e4a303e9f7a499e33237a08e4516ae04337f6b Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 14:11:52 +0600 Subject: [PATCH 08/29] docs: remove `value` property from README since it should be private / encapsulated --- .../@stdlib/number/uint64/ctor/README.md | 26 ++++--------------- .../@stdlib/number/uint64/ctor/lib/main.js | 1 + 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/README.md b/lib/node_modules/@stdlib/number/uint64/ctor/README.md index e65638f13020..c671f2193dcb 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/README.md +++ b/lib/node_modules/@stdlib/number/uint64/ctor/README.md @@ -84,20 +84,7 @@ var nbytes = x.BYTES_PER_ELEMENT; ### Instance -A `Uint64` instance has the following properties... - -#### value - -A **read-only** property returning the underlying value as a number. - -```javascript -var x = new Uint64( 5 ); - -var v = x.value; -// returns 5.0 -``` - -* * * +A `Uint64` instance has the following methods... ## Methods @@ -110,7 +97,7 @@ These methods do **not** mutate a `Uint64` instance and, instead return an unsig Returns a string representation of a `Uint64` instance. ```javascript -var x = new Uint64( 5.0 ); +var x = new Uint64( 5 ); var str = x.toString(); // returns '5' ``` @@ -120,7 +107,7 @@ var str = x.toString(); Returns a [JSON][json] representation of a `Uint64` instance. [`JSON.stringify()`][mdn-json-stringify] implicitly calls this method when stringifying a `Uint64` instance. ```javascript -var x = new Uint64( 5.0 ); +var x = new Uint64( 5 ); var o = x.toJSON(); /* @@ -138,7 +125,7 @@ To [revive][mdn-json-parse] a `Uint64` number from a [JSON][json] `string`, see Converts a `Uint64` instance to a primitive value. ```javascript -var x = new Uint64( 5.0 ); +var x = new Uint64( 5 ); var v = x.valueOf(); // returns 5.0 ``` @@ -156,7 +143,7 @@ var v = x.valueOf(); ## Notes - The underlying value is stored as an unsigned 64-bit integer. -- An unsigned 64-bit integer has a range of [`0`, `2^64-1`]. +- An unsigned 64-bit integer has a range of \[`0`, `2^64-1`\]. @@ -183,9 +170,6 @@ console.log( 'type: %s', typeof x ); console.log( 'str: %s', x ); // => 'str: 1234' -console.log( 'value: %d', x.value ); -// => 'value: 1234' - console.log( 'JSON: %s', JSON.stringify( x ) ); // => 'JSON: {"type":"Uint64","value":"1234"}' ``` 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 cad82d80950b..bfc49d2872e5 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -65,6 +65,7 @@ function Uint64( value ) { // Or an object with high and low props? if ( isBigInt( value ) ) { + // TODO: make the value property private setEnumerableReadOnly( this, 'value', asBigUint64( value ) ); } else if ( isUint32Array( value ) ) { From b438d535e9369b1dc3d6bdac4a3ef990309f92be Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 15:20:07 +0600 Subject: [PATCH 09/29] test: implement initial tests --- .../number/uint64/ctor/lib/tostring.js | 1 + .../@stdlib/number/uint64/ctor/test/test.js | 224 ++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/test/test.js diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js index 3a657433f456..bec1f1fc6399 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js @@ -38,6 +38,7 @@ function toString( base ) { // eslint-disable-line stdlib/no-redeclare } // TODO: implement double word base conversion + // TODO: should we support base conversion? return '?'; } diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js new file mode 100644 index 000000000000..31434aac8e31 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -0,0 +1,224 @@ +/* eslint-disable stdlib/no-unnecessary-nested-functions */ +/* eslint-disable require-jsdoc */ +/* eslint-disable no-restricted-syntax */ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var tape = require( 'tape' ); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var Uint64 = require( './../lib' ); + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof Uint64, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function is a constructor', function test( t ) { + var x = new Uint64( 5 ); + t.strictEqual( x instanceof Uint64, true, 'is an instance' ); + t.end(); +}); + +tape( 'the constructor throws an error if not provided a number or string or number[] or Uint32Array or BigInt', function test( t ) { + var values; + var i; + + values = [ + null, + void 0, + true, + false, + [], + {}, + function noop() {} + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var x = new Uint64( value ); // eslint-disable-line no-unused-vars + }; + } +}); + +tape( 'the constructor requires the `new` keyword', function test( t ) { + var ctor = Uint64; + t.throws( foo, TypeError, 'throws an error' ); + t.end(); + + function foo() { + ctor( 5 ); + } +}); + +tape( 'the constructor has a read-only `name` property', function test( t ) { + t.strictEqual( hasOwnProp( Uint64, 'name' ), true, 'has property' ); + t.strictEqual( Uint64.name, 'Uint64', 'returns expected value' ); + t.throws( foo, Error, 'throws an error' ); + t.end(); + + function foo() { + Uint64.name = 'Foo'; + } +}); + +tape( 'the constructor has a read-only `BYTES_PER_ELEMENT` property', function test( t ) { + t.strictEqual( hasOwnProp( Uint64, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( Uint64.BYTES_PER_ELEMENT, 8, 'returns expected value' ); + t.throws( foo, Error, 'throws an error' ); + t.end(); + + function foo() { + Uint64.BYTES_PER_ELEMENT = 4; + } +}); + +tape( 'the constructor prototype has a read-only `BYTES_PER_ELEMENT` property', function test( t ) { + t.strictEqual( hasOwnProp( Uint64.prototype, 'BYTES_PER_ELEMENT' ), true, 'has property' ); + t.strictEqual( Uint64.prototype.BYTES_PER_ELEMENT, 8, 'returns expected value' ); + t.throws( foo, Error, 'throws an error' ); + t.end(); + + function foo() { + Uint64.prototype.BYTES_PER_ELEMENT = 4; + } +}); + +// TODO: commented out because value should be private right? +/* +tape( 'the constructor returns an instance having a property for accessing the underlying value', function test( t ) { + var x = new Uint64( 5 ); + t.strictEqual( x.value, 5, 'returns expected value' ); + t.end(); +}); + +tape( 'the constructor returns an instance which throws an error when attempting to mutate the value', function test( t ) { + var x = new Uint64( 5 ); + t.throws( foo, Error, 'throws an error' ); + t.end(); + + function foo() { + x.value = -5; + } +}); + +tape( 'the constructor returns an instance which stores a provided value as a half-precision floating-point number', function test( t ) { + var x = new Uint64( 3.14 ); + t.strictEqual( x.value, 3.140625, 'returns expected value' ); + t.end(); +}); +*/ + +tape( 'the constructor returns an instance which supports serializing an instance as a string', function test( t ) { + var x; + + x = new Uint64( 5 ); + t.strictEqual( x.toString(), '5', 'returns expected value' ); + + // TODO: should we support base conversion in toString? + /* + x = new Uint64( 255 ); + t.strictEqual( x.toString(16), 'ff', 'returns expected value' ); + */ + t.end(); +}); + +tape( 'the constructor returns an instance which supports serializing an instance as a JSON object', function test( t ) { + var expected; + var x; + + x = new Uint64( 5 ); + expected = { + 'type': 'Uint64', + 'value': '5' + }; + t.deepEqual( x.toJSON(), expected, 'returns expected value' ); + t.strictEqual( JSON.stringify( x ), JSON.stringify( expected ), 'returns expected value' ); + + // TODO: test array format of toJSON if applicable after review + + t.end(); +}); + +tape( 'the constructor returns an instance which supports converting an instance to a primitive value', function test( t ) { + var x; + + x = new Uint64( 5 ); + t.strictEqual( x.valueOf(), 5, 'returns expected value' ); + + x = new Uint64( [ 1, 0 ] ); + t.strictEqual( x.valueOf(), 4294967296, 'returns expected value' ); + + x = new Uint64( 0 ); + t.strictEqual( x.valueOf(), 0, 'returns expected value' ); + + t.end(); +}); + +// TODO: we discussed that direct operations will not be supported without the functional utils +// And hould we actually remove the ToPrimitive function? +/* +tape( 'the constructor returns an instance which supports implicit type coercion', function test( t ) { + var x; + var y; + + x = new Uint64( 10.0 ); + t.strictEqual( x + 5, 15.0, 'returns expected value' ); + t.strictEqual( x * 2, 20.0, 'returns expected value' ); + + x = new Uint64( 3.0 ); + y = new Uint64( 2.0 ); + t.strictEqual( x + y, 5, 'returns expected value' ); + + t.end(); +}); + + +tape( 'if an environment supports `Symbol.toPrimitive`, the constructor returns an instance which supports type coercion', function test( t ) { + var x; + + if ( !hasToPrimitiveSymbolSupport() ) { + t.ok( true, 'environment does not support Symbol.toPrimitive' ); + t.end(); + return; + } + x = new Uint64( 5 ); + + t.strictEqual( x[ ToPrimitiveSymbol ]( 'number' ), 5, 'returns expected value' ); + t.strictEqual( x[ ToPrimitiveSymbol ]( 'default' ), 5, 'returns expected value' ); + t.strictEqual( x[ ToPrimitiveSymbol ]( 'string' ), 5, 'returns expected value' ); + + x = new Uint64( -3.14 ); + t.strictEqual( x[ ToPrimitiveSymbol ](), -3.140625, 'returns expected value' ); + + t.end(); +}); +*/ + +// TODO: add more tests like truncation, array size check, etc From 77609f7e70f0564f43ace2538d63a2b71ef616b3 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 15:23:12 +0600 Subject: [PATCH 10/29] docs: update todo comment --- lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 bfc49d2872e5..b2c8df95b0cc 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -45,7 +45,8 @@ var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redecl * Unsigned 64-bit integer constructor. * * @constructor -* @param {number|string|number[]|Uint32Array|BigInt} value - numeric value or high low words or BigInt // TODO: Which ones should we keep and discard? +* @param {number|string|number[]|Uint32Array|BigInt} value - numeric value or high low words or BigInt +* TODO: Which ones should we keep and discard? Should we support any arraylike argument? * @throws {TypeError} must invoke using the `new` keyword * @throws {TypeError} value must be a number or bla bla bla // TODO: update after review * @returns {Uint64} Unsigned 64-bit integer @@ -65,7 +66,7 @@ function Uint64( value ) { // Or an object with high and low props? if ( isBigInt( value ) ) { - // TODO: make the value property private + // TODO: make the `value` property private setEnumerableReadOnly( this, 'value', asBigUint64( value ) ); } else if ( isUint32Array( value ) ) { From e367b179c69b82f8c9ee58404f114d6a99fe8b9c Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 15:32:42 +0600 Subject: [PATCH 11/29] bench: add initial benchmarks --- .../number/uint64/ctor/benchmark/benchmark.js | 121 ++++++++++++++++++ .../@stdlib/number/uint64/ctor/test/test.js | 3 +- 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js b/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js new file mode 100644 index 000000000000..87550a2d285c --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js @@ -0,0 +1,121 @@ +/* eslint-disable no-restricted-syntax */ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var bench = require( '@stdlib/bench' ); +var randu = require( '@stdlib/random/base/randu' ); +var isnan = require( '@stdlib/math/base/assert/is-nan' ); +var format = require( '@stdlib/string/format' ); +var pkg = require( './../package.json' ).name; +var Uint64 = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var z; + var i; + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + z = new Uint64( i ); + if ( isnan( z ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( !( z instanceof Uint64 ) ) { + b.fail( 'should return a Uint64 instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +// TODO: because `value` should be private? + +/* +bench( format( '%s::get:value', pkg ), function benchmark( b ) { + var v; + var z; + var i; + + z = new Uint64( randu() ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + v = z.value; + if ( isnan( v ) ) { + b.fail( 'should not return NaN' ); + } + } + b.toc(); + if ( isnan( v ) ) { + b.fail( 'should not return NaN' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); +*/ + +bench( format( '%s:toString', pkg ), function benchmark( b ) { + var o; + var z; + var i; + + z = new Uint64( randu() ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + o = z.toString(); + if ( typeof o !== 'string' ) { + b.fail( 'should return a string' ); + } + } + b.toc(); + if ( typeof o !== 'string' ) { + b.fail( 'should return a string' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( format( '%s:toJSON', pkg ), function benchmark( b ) { + var o; + var z; + var i; + + z = new Uint64( randu() ); + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + o = z.toJSON(); + if ( typeof o !== 'object' ) { + b.fail( 'should return an object' ); + } + } + b.toc(); + if ( typeof o !== 'object' ) { + b.fail( 'should return an object' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); 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 31434aac8e31..5afc31573244 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -53,6 +53,8 @@ tape( 'the constructor throws an error if not provided a number or string or num false, [], {}, + + // eslint-disable-next-line no-empty-function function noop() {} ]; for ( i = 0; i < values.length; i++ ) { @@ -199,7 +201,6 @@ tape( 'the constructor returns an instance which supports implicit type coercion t.end(); }); - tape( 'if an environment supports `Symbol.toPrimitive`, the constructor returns an instance which supports type coercion', function test( t ) { var x; From aa937a470646f85ad650aea249b9194151d01d45 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 15:50:01 +0600 Subject: [PATCH 12/29] docs: add types --- .../@stdlib/number/uint64/ctor/docs/repl.txt | 63 +++++++++++ .../number/uint64/ctor/docs/types/index.d.ts | 105 ++++++++++++++++++ .../number/uint64/ctor/docs/types/test.ts | 65 +++++++++++ .../@stdlib/number/uint64/ctor/lib/index.js | 2 +- .../@stdlib/number/uint64/ctor/test/test.js | 2 +- 5 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/docs/types/test.ts diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt b/lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt new file mode 100644 index 000000000000..da8e53402578 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt @@ -0,0 +1,63 @@ + +{{alias}}( value ) + Unsigned 64-bit integer constructor. + + Parameters + ---------- + value: number | string | number[] | Uint32Array | BigInt + Numeric or BigInt or composite value. + + Returns + ------- + v: Uint64 + Unsigned 64-bit integer. + + Examples + -------- + > var x = new {{alias}}( 5 ) + + > x.toString() + '5' + + +{{alias}}.name + Constructor name. + + Examples + -------- + > var str = {{alias}}.name + 'Uint64' + + +{{alias}}.BYTES_PER_ELEMENT + Size (in bytes) of the underlying value. + + Returns + ------- + s: integer + Size (in bytes) of the underlying value. + + Examples + -------- + > var s = {{alias}}.BYTES_PER_ELEMENT + 8 + + +{{alias}}.prototype.BYTES_PER_ELEMENT + Size (in bytes) of the underlying value. + + Returns + ------- + s: integer + Size (in bytes) of the underlying value. + + Examples + -------- + > var x = new {{alias}}( 5 ) + + > var s = x.BYTES_PER_ELEMENT + 8 + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts new file mode 100644 index 000000000000..8b0c90888c51 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts @@ -0,0 +1,105 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// TypeScript Version: 4.1 + +/** +* Unsigned 64-bit integer. +*/ +declare class Uint64 { + /** + * Unsigned 64-bit integer constructor. + * + * @param value - numeric value + * @returns unsigned 64-bit integer + * + * @example + * var x = new Uint64( 5 ); + * // returns + */ + constructor( value: number | string | number[] | Uint32Array | BigInt ); + // TODO: do we need to import Uint32Array and BigInt here as well? + + /** + * Read-only property returning the value. + * + * @returns value + */ + // readonly value: number; + // TODO: because private + + /** + * Size (in bytes) of the underlying value. + * + * @returns size of the underlying value. + * + * @example + * var nbytes = Uint64.BYTES_PER_ELEMENT; + * // returns 8 + */ + readonly BYTES_PER_ELEMENT: 8; + + /** + * Serializes an unsigned 64-bit integer as a string. + * + * @returns serialized unsigned 64-bit integer + * + * @example + * var x = new Uint64( 5 ); + * + * var str = x.toString(); + * // returns '5' + */ + toString(): string; + + /** + * Serializes an unsigned 64-bit integer as a JSON object. + * + * ## Notes + * + * - `JSON.stringify()` implicitly calls this method when stringifying a `Uint64` instance. + * + * + * @returns serialized unsigned 64-bit integer + * + * @example + * var x = new Uint64( 5 ); + * + * var obj = x.toJSON(); + * // returns { 'type': 'Uint64', 'value': '5' } + */ + toJSON(): any; + + /** + * Converts an unsigned 64-bit integer to a primitive value. + * + * @returns primitive value + * + * @example + * var x = new Uint64( 5 ); + * + * var v = x.valueOf(); + * // returns 5.0 + */ + valueOf(): number; +} + + +// EXPORTS // + +export = Uint64; diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/test.ts b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/test.ts new file mode 100644 index 000000000000..eb673559024a --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/test.ts @@ -0,0 +1,65 @@ +/* +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable @typescript-eslint/no-unused-expressions */ + +import Uint64 = require( './index' ); + + +// TESTS // + +// The function returns a Unsigned 64-bit integer with the expected properties... +{ + const x = new Uint64( 5 ); // $ExpectType Uint64 + + // x.value; // $ExpectType number + // TODO: delete later cz private + x.BYTES_PER_ELEMENT; // $ExpectType 8 +} + +// Unsigned 64-bit integer comes with a `toString` method to serialize a number as a string... +{ + const x = new Uint64( 5 ); // $ExpectType Uint64 + + x.toString(); // $ExpectType string +} + +// Unsigned 64-bit integer comes with a `toJSON` method to serialize a number as a JSON object.... +{ + const x = new Uint64( 5 ); // $ExpectType Uint64 + + x.toJSON(); // $ExpectType any +} + +// Unsigned 64-bit integer comes with a `valueOf` method to serialize a number to a primitive value... +{ + const x = new Uint64( 5 ); // $ExpectType Uint64 + + x.valueOf(); // $ExpectType number +} + +// The compiler throws an error if the constructor is invoked without the `new` keyword... +{ + Uint64( 5 ); // $ExpectError +} + +// The compiler throws an error if the constructor is provided an unsupported number of arguments... +{ + new Uint64( ); // $ExpectError + new Uint64( 5, 3 ); // $ExpectError +} diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js index 6eb0c1ad8292..a30fe84ad615 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js @@ -26,7 +26,7 @@ * @example * var Uint64 = require( '@stdlib/number/uint64/ctor' ); * -* var x = new Uint64( 5.0 ); +* var x = new Uint64( 5 ); * // returns */ 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 5afc31573244..0dbe74bb3a38 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -130,7 +130,7 @@ tape( 'the constructor returns an instance which throws an error when attempting } }); -tape( 'the constructor returns an instance which stores a provided value as a half-precision floating-point number', function test( t ) { +tape( 'the constructor returns an instance which stores a provided value as an unsigned 64-bit integer', function test( t ) { var x = new Uint64( 3.14 ); t.strictEqual( x.value, 3.140625, 'returns expected value' ); t.end(); From de8ca592f382773731a78c23fd8e023805085039 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 15:55:45 +0600 Subject: [PATCH 13/29] docs: add javascript example --- .../number/uint64/ctor/examples/index.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js b/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js new file mode 100644 index 000000000000..4860246c8d8a --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js @@ -0,0 +1,32 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2025 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +var Uint64 = require( './../lib' ); + +var x = new Uint64( 5 ); + +console.log( 'type: %s', typeof x ); +// => 'type: object' + +console.log( 'str: %s', x ); +// => 'str: 5' + +console.log( 'JSON: %s', JSON.stringify( x ) ); +// => 'JSON: {"type":"Uint64","value":"5"}' From 3420ebf3776ae982cc769cf0112495e0006d5e19 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 16:23:29 +0600 Subject: [PATCH 14/29] fix: resovle lint errors --- lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt | 2 +- .../@stdlib/number/uint64/ctor/docs/types/index.d.ts | 2 +- lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js | 4 ++-- lib/node_modules/@stdlib/number/uint64/ctor/test/test.js | 7 +------ 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt b/lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt index da8e53402578..e994f8b39a08 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/repl.txt @@ -4,7 +4,7 @@ Parameters ---------- - value: number | string | number[] | Uint32Array | BigInt + value: number | string | Array | Uint32Array | BigInt Numeric or BigInt or composite value. Returns diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts index 8b0c90888c51..a90ebb27cd99 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts @@ -32,7 +32,7 @@ declare class Uint64 { * var x = new Uint64( 5 ); * // returns */ - constructor( value: number | string | number[] | Uint32Array | BigInt ); + constructor( value: number | string | Array | Uint32Array | BigInt ); // TODO: do we need to import Uint32Array and BigInt here as well? /** 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 b2c8df95b0cc..fd354d05e641 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -45,7 +45,7 @@ var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redecl * Unsigned 64-bit integer constructor. * * @constructor -* @param {number|string|number[]|Uint32Array|BigInt} value - numeric value or high low words or BigInt +* @param {number|string|Array|Uint32Array|BigInt} value - numeric value or high low words or BigInt * TODO: Which ones should we keep and discard? Should we support any arraylike argument? * @throws {TypeError} must invoke using the `new` keyword * @throws {TypeError} value must be a number or bla bla bla // TODO: update after review @@ -127,7 +127,7 @@ function Uint64( value ) { } } else { - throw new TypeError( format( 'invalid argument. Must provide a number or string or number[] or Uint32Array or BigInt. Value: `%s`.', value ) ); + throw new TypeError( format( 'invalid argument. Must provide a number or string or Array or Uint32Array or BigInt. Value: `%s`.', value ) ); } 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 0dbe74bb3a38..62c30e28551b 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -1,6 +1,3 @@ -/* eslint-disable stdlib/no-unnecessary-nested-functions */ -/* eslint-disable require-jsdoc */ -/* eslint-disable no-restricted-syntax */ /** * @license Apache-2.0 * @@ -42,7 +39,7 @@ tape( 'the function is a constructor', function test( t ) { t.end(); }); -tape( 'the constructor throws an error if not provided a number or string or number[] or Uint32Array or BigInt', function test( t ) { +tape( 'the constructor throws an error if not provided a number or string or Array or Uint32Array or BigInt', function test( t ) { var values; var i; @@ -53,8 +50,6 @@ tape( 'the constructor throws an error if not provided a number or string or num false, [], {}, - - // eslint-disable-next-line no-empty-function function noop() {} ]; for ( i = 0; i < values.length; i++ ) { From fc00588b06086628c32aedb5183b220c7ba70bf1 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 13 Mar 2026 18:41:14 +0600 Subject: [PATCH 15/29] fix: resolve lint errors --- .../@stdlib/number/uint64/ctor/benchmark/benchmark.js | 1 - lib/node_modules/@stdlib/number/uint64/ctor/test/test.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js b/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js index 87550a2d285c..30a4b9414799 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js @@ -1,4 +1,3 @@ -/* eslint-disable no-restricted-syntax */ /** * @license Apache-2.0 * 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 62c30e28551b..5f90aa1d0390 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -179,7 +179,7 @@ tape( 'the constructor returns an instance which supports converting an instance }); // TODO: we discussed that direct operations will not be supported without the functional utils -// And hould we actually remove the ToPrimitive function? +// And should we actually remove the ToPrimitive function? /* tape( 'the constructor returns an instance which supports implicit type coercion', function test( t ) { var x; From afbeaa2e88dd48a630f1fceae3d7671bf62c5cf0 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 03:05:13 +0600 Subject: [PATCH 16/29] feat: implement toString with high low words --- .../number/uint64/ctor/lib/tostring.js | 216 +++++++++++++++++- 1 file changed, 210 insertions(+), 6 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js index bec1f1fc6399..27e06aba8956 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js @@ -1,3 +1,5 @@ +/* eslint-disable vars-on-top */ +/* eslint-disable stdlib/vars-order */ /* eslint-disable no-invalid-this */ /** * @license Apache-2.0 @@ -19,27 +21,229 @@ 'use strict'; +// MODULES // + +var lpad = require( '@stdlib/string/left-pad' ); + +// Helper constants for toString base conversion +var TWO_16 = 1 << 16; + +var POWERMAP = { + '2': { + 'power': 32, + 'divisor': 4294967296 + }, + '3': { + 'power': 20, + 'divisor': 3486784401 + }, + '4': { + 'power': 16, + 'divisor': 4294967296 + }, + '5': { + 'power': 13, + 'divisor': 1220703125 + }, + '6': { + 'power': 12, + 'divisor': 2176782336 + }, + '7': { + 'power': 11, + 'divisor': 1977326743 + }, + '8': { + 'power': 10, + 'divisor': 1073741824 + }, + '9': { + 'power': 10, + 'divisor': 3486784401 + }, + '10': { + 'power': 9, + 'divisor': 1000000000 + }, + '11': { + 'power': 9, + 'divisor': 2357947691 + }, + '12': { + 'power': 8, + 'divisor': 429981696 + }, + '13': { + 'power': 8, + 'divisor': 815730721 + }, + '14': { + 'power': 8, + 'divisor': 1475789056 + }, + '15': { + 'power': 8, + 'divisor': 2562890625 + }, + '16': { + 'power': 8, + 'divisor': 4294967296 + }, + '17': { + 'power': 7, + 'divisor': 410338673 + }, + '18': { + 'power': 7, + 'divisor': 612220032 + }, + '19': { + 'power': 7, + 'divisor': 893871739 + }, + '20': { + 'power': 7, + 'divisor': 1280000000 + }, + '21': { + 'power': 7, + 'divisor': 1801088541 + }, + '22': { + 'power': 7, + 'divisor': 2494357888 + }, + '23': { + 'power': 7, + 'divisor': 3404825447 + }, + '24': { + 'power': 6, + 'divisor': 191102976 + }, + '25': { + 'power': 6, + 'divisor': 244140625 + }, + '26': { + 'power': 6, + 'divisor': 308915776 + }, + '27': { + 'power': 6, + 'divisor': 387420489 + }, + '28': { + 'power': 6, + 'divisor': 481890304 + }, + '29': { + 'power': 6, + 'divisor': 594823321 + }, + '30': { + 'power': 6, + 'divisor': 729000000 + }, + '31': { + 'power': 6, + 'divisor': 887503681 + }, + '32': { + 'power': 6, + 'divisor': 1073741824 + }, + '33': { + 'power': 6, + 'divisor': 1291467969 + }, + '34': { + 'power': 6, + 'divisor': 1544804416 + }, + '35': { + 'power': 6, + 'divisor': 1838265625 + }, + '36': { + 'power': 6, + 'divisor': 2176782336 + } +}; + + // MAIN // /** -* Serializes an unsigned 64-bit integer as a string. +* Serializes an unsigned 64-bit integer as a string in the specified base. * * @private -* @param {number} base - radix -* @returns {string} serialized unsigned 64-bit integer +* @param {number} base - The radix (base) to use for string conversion +* @returns {string} The serialized unsigned 64-bit integer as a string. +* +* **Note** +* This implementation handles 64-bit unsigned integers represented as either a BigInt or a pair of 32-bit words ([high, low]). +* For non-BigInt values, the conversion uses a precomputed POWERMAP to select a divisor and chunk size for efficient base conversion. +* The divisor values are chosen to be close to powers of 2^32 for each supported base, which is an unusual but efficient approach for chunked conversion. +* The function pads the lower chunk with leading zeros to ensure correct digit alignment. */ function toString( base ) { // eslint-disable-line stdlib/no-redeclare // eslint-disable-next-line no-undefined if ( base === undefined ) { base = 10; } + // TODO: validate base range (between 2 and 36) if ( typeof this.value === 'bigint' ) { return this.value.toString( base ); } - // TODO: implement double word base conversion - // TODO: should we support base conversion? - return '?'; + var qr = divmod( this.value, POWERMAP[ base ].divisor ); + var sq = qr[ 0 ].toString( base ); + var sr = qr[ 1 ].toString( base ); + if ( sq === '0' ) { + sq = ''; + } + sr = lpad( sr, POWERMAP[ base ].power, '0' ); + return sq + sr; +} + +/** +* Performs division and modulo for an unsigned 64-bit integer represented as high-low words. +* +* @private +* @param {Uint32Array|Array} words - [high, low] 32-bit words +* @param {number} divisor - positive integer close to `2^32` +* @returns {Array} [ quotient, remainder ] +* +* @example +* var x = divmod( [ 0, 5 ] ); +* // returns [ 0, NaN ] +*/ +function divmod( words, divisor ) { + var hi = words[0] >>> 0; + var lo = words[1] >>> 0; + + var quo = ( hi / divisor ) >>> 0; + var rem = hi - ( divisor * quo ); + var qrd; + + if (divisor === 0x100000000) { + return [ hi, lo ]; + } + + rem = ( rem * TWO_16 ) + ( lo >>> 16 ); + qrd = ( rem / divisor ) >>> 0; + + quo = ( quo * TWO_16 ) + qrd; + rem -= divisor * qrd; + + rem = ( rem * TWO_16 ) + ( lo & 0xffff ); + qrd = ( rem / divisor ) >>> 0; + + quo = ( quo * TWO_16 ) + qrd; + rem -= divisor * qrd; + + return [quo, rem]; } From 9d932db6cde4787e0e43b6d0b365dc60fadca560 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 03:08:52 +0600 Subject: [PATCH 17/29] feat: update Uint64 constructor to support setting preferred representation --- .../@stdlib/number/uint64/ctor/lib/main.js | 85 +++++++++++++------ 1 file changed, 59 insertions(+), 26 deletions(-) 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 fd354d05e641..6643bf1216c5 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -1,3 +1,4 @@ +/* eslint-disable max-len */ /** * @license Apache-2.0 * @@ -21,6 +22,7 @@ // MODULES // var BigInt = require( '@stdlib/bigint/ctor' ); +var Number = require( '@stdlib/number/ctor' ); var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); var Uint32Array = require( '@stdlib/array/uint32' ); var format = require( '@stdlib/string/format' ); @@ -38,6 +40,10 @@ var toStr = require( './tostring.js' ); var toJSON = require( './tojson.js' ); var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redeclare +// TODO: should we add asm type annotations aggressively? +var MAX_UINT32 = 0xffffffff; +var TWO_32 = 0x100000000; + // MAIN // @@ -47,6 +53,7 @@ var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redecl * @constructor * @param {number|string|Array|Uint32Array|BigInt} value - numeric value or high low words or BigInt * TODO: Which ones should we keep and discard? Should we support any arraylike argument? +* @param {boolean} useHighLow - use double word Uint32Array representation * @throws {TypeError} must invoke using the `new` keyword * @throws {TypeError} value must be a number or bla bla bla // TODO: update after review * @returns {Uint64} Unsigned 64-bit integer @@ -55,8 +62,11 @@ var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redecl * var x = new Uint64( 5 ); * // returns */ -function Uint64( value ) { - var hasBigInt = hasBigIntSupport(); +function Uint64( value, useHighLow ) { + var high; + var low; + useHighLow |= !hasBigIntSupport(); + if ( !( this instanceof Uint64 ) ) { throw new TypeError( 'invalid invocation. Constructor must be called with the `new` keyword.' ); } @@ -65,17 +75,22 @@ function Uint64( value ) { // Are there other better alternative instead of Uint32Array? How is plain old number array? // Or an object with high and low props? + // TODO: make the `value` property private + if ( isBigInt( value ) ) { - // TODO: make the `value` property private - setEnumerableReadOnly( this, 'value', asBigUint64( value ) ); + value = asBigUint64( value ); + if ( useHighLow ) { + high = Number( value >> BigInt( 32 ) ); + low = Number( value & BigInt( MAX_UINT32 ) ); + value = new Uint32Array( [ high, low ] ); + + // TODO: should we use value[0] = high, value[1] = low instead to avoid the intermediate array allocation? + } } else if ( isUint32Array( value ) ) { if ( value.length === 2 ) { - if ( hasBigInt ) { - setEnumerableReadOnly( this, 'value', ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ) ); - } - else { - setEnumerableReadOnly( this, 'value', value ); + if ( !useHighLow ) { + value = ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ); } } else { @@ -85,13 +100,18 @@ function Uint64( value ) { else if ( isArray( value ) ) { if ( value.length === 2 ) { if ( typeof value[ 0 ] === 'number' && typeof value[ 1 ] === 'number' ) { - value[ 0 ] >>>= 0; - value[ 1 ] >>>= 0; - if ( hasBigInt ) { - setEnumerableReadOnly( this, 'value', ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ) ); + if ( value[ 0 ] >= 0 && value[ 0 ] <= MAX_UINT32 && value[ 1 ] >= 0 && value[ 1 ] <= MAX_UINT32 ) { + value[ 0 ] >>>= 0; + value[ 1 ] >>>= 0; + if ( useHighLow ) { + value = new Uint32Array( value ); + } + else { + value = ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ); + } } else { - setEnumerableReadOnly( this, 'value', new Uint32Array( value ) ); + throw new TypeError( format( 'invalid argument. Provided numbers must be between 0 and %s. Value: `%s`.', MAX_UINT32, value ) ); } } else { @@ -103,7 +123,11 @@ function Uint64( value ) { } } else if ( isString( value ) ) { - if ( hasBigInt ) { + if ( useHighLow ) { + // TODO: decompose into high low + setEnumerableReadOnly( this, 'value', new Uint32Array( [ 0, 0 ] ) ); + } + else { try { setEnumerableReadOnly( this, 'value', asBigUint64( BigInt( value ) ) ); } @@ -112,23 +136,27 @@ function Uint64( value ) { throw new TypeError( format( 'invalid argument. Could not convert string to BigInt. Value: `%s`.', value ) ); } } - else { - // TODO: decompose into high low - setEnumerableReadOnly( this, 'value', new Uint32Array( [ 0, 0 ] ) ); - } } else if ( isNumber( value ) ) { - value >>>= 0; - if ( hasBigInt ) { - setEnumerableReadOnly( this, 'value', asBigUint64( BigInt( value ) ) ); + if ( value >= 0 && Number.isSafeInteger( value ) ) { + if ( useHighLow ) { + high = ( value / TWO_32 ) >>> 0; + low = value >>> 0; + value = new Uint32Array( [ high, low ] ); + } + else { + value = asBigUint64( BigInt( value ) ); + } } else { - setEnumerableReadOnly( this, 'value', new Uint32Array( [ 0, value ] ) ); + throw new TypeError( format( 'invalid argument. Provided number must be between 0 and %s. Value: `%s`.', Number.MAX_SAFE_INTEGER, value ) ); } } else { throw new TypeError( format( 'invalid argument. Must provide a number or string or Array or Uint32Array or BigInt. Value: `%s`.', value ) ); } + + setEnumerableReadOnly( this, 'value', value ); return this; } @@ -186,10 +214,15 @@ setReadOnly( Uint64.prototype, 'BYTES_PER_ELEMENT', 8 ); * @returns {string} serialized unsigned 64-bit integer number * * @example -* var x = new Uint64( 5 ); -* -* var str = x.toString(); +* var str = new Uint64( 5 ).toString(); * // returns '5' +* +* str = new Uint64( [ 1, 0 ] ).toString(); +* // returns '4294967296' +* +* str = new Uint64( 100000000001 ).toString(); +* // returns '100000000001' +* */ setReadOnly( Uint64.prototype, 'toString', toStr ); From 3926d9add403dcf69b6a164a46fdd53f490cc6a4 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 03:10:05 +0600 Subject: [PATCH 18/29] chore: remove unused paths from package.json --- lib/node_modules/@stdlib/number/uint64/ctor/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/package.json b/lib/node_modules/@stdlib/number/uint64/ctor/package.json index 56db7dbfb7fe..b7753d345528 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/package.json +++ b/lib/node_modules/@stdlib/number/uint64/ctor/package.json @@ -18,9 +18,7 @@ "benchmark": "./benchmark", "doc": "./docs", "example": "./examples", - "include": "./include", "lib": "./lib", - "src": "./src", "test": "./test" }, "types": "./docs/types", From f1ab12d5edbdc06e78be179004bd5c142be8b31b Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 03:31:42 +0600 Subject: [PATCH 19/29] bench: fix benchmark error --- .../@stdlib/number/uint64/ctor/benchmark/benchmark.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js b/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js index 30a4b9414799..6bd879e1b100 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ // MODULES // var bench = require( '@stdlib/bench' ); -var randu = require( '@stdlib/random/base/randu' ); +var randi = require( '@stdlib/random/base/randi' ); var isnan = require( '@stdlib/math/base/assert/is-nan' ); var format = require( '@stdlib/string/format' ); var pkg = require( './../package.json' ).name; @@ -80,7 +80,7 @@ bench( format( '%s:toString', pkg ), function benchmark( b ) { var z; var i; - z = new Uint64( randu() ); + z = new Uint64( randi() ); b.tic(); for ( i = 0; i < b.iterations; i++ ) { @@ -102,7 +102,7 @@ bench( format( '%s:toJSON', pkg ), function benchmark( b ) { var z; var i; - z = new Uint64( randu() ); + z = new Uint64( randi() ); b.tic(); for ( i = 0; i < b.iterations; i++ ) { From b2fd1f6ad8d76e98c32f917f6ac7cc5cc98e1ebf Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 03:32:01 +0600 Subject: [PATCH 20/29] chore: update copyright years --- .../@stdlib/number/uint64/ctor/docs/types/index.d.ts | 2 +- .../@stdlib/number/uint64/ctor/docs/types/test.ts | 2 +- .../@stdlib/number/uint64/ctor/examples/index.js | 2 +- lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js | 2 +- .../@stdlib/number/uint64/ctor/lib/tostring.js | 7 ++++--- lib/node_modules/@stdlib/number/uint64/ctor/test/test.js | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts index a90ebb27cd99..d88e404c90ed 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts @@ -1,7 +1,7 @@ /* * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/test.ts b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/test.ts index eb673559024a..5185ec865317 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/test.ts +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/test.ts @@ -1,7 +1,7 @@ /* * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js b/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js index 4860246c8d8a..f2c9595e4695 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js index a30fe84ad615..34c9e26b59a8 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/index.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js index 27e06aba8956..05711889b750 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js @@ -1,6 +1,3 @@ -/* eslint-disable vars-on-top */ -/* eslint-disable stdlib/vars-order */ -/* eslint-disable no-invalid-this */ /** * @license Apache-2.0 * @@ -19,6 +16,10 @@ * limitations under the License. */ +/* eslint-disable vars-on-top */ +/* eslint-disable stdlib/vars-order */ +/* eslint-disable no-invalid-this */ + 'use strict'; // MODULES // 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 5f90aa1d0390..f2348a43c514 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -1,7 +1,7 @@ /** * @license Apache-2.0 * -* Copyright (c) 2025 The Stdlib Authors. +* Copyright (c) 2026 The Stdlib Authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From b6e19aac11bdfa3c924c2d07ca1359d014e56b80 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 21:20:59 +0600 Subject: [PATCH 21/29] test: add more tests --- .../@stdlib/number/uint64/ctor/test/test.js | 221 +++++++++++++++++- 1 file changed, 213 insertions(+), 8 deletions(-) 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 f2348a43c514..377047a46c79 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -21,7 +21,13 @@ // MODULES // var tape = require( 'tape' ); +var BigInt = require( '@stdlib/bigint/ctor' ); +var hasBigIntSupport = require( '@stdlib/assert/has-bigint-support' ); +var hasToPrimSymSupport = require( '@stdlib/assert/has-to-primitive-symbol-support' ); var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var isUint32Array = require( '@stdlib/assert/is-uint32array' ); +var Uint32Array = require( '@stdlib/array/uint32' ); +var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); var Uint64 = require( './../lib' ); @@ -111,7 +117,7 @@ tape( 'the constructor prototype has a read-only `BYTES_PER_ELEMENT` property', /* tape( 'the constructor returns an instance having a property for accessing the underlying value', function test( t ) { var x = new Uint64( 5 ); - t.strictEqual( x.value, 5, 'returns expected value' ); + t.strictEqual( x.value.toString(), '5', 'returns expected value' ); t.end(); }); @@ -126,23 +132,202 @@ tape( 'the constructor returns an instance which throws an error when attempting }); tape( 'the constructor returns an instance which stores a provided value as an unsigned 64-bit integer', function test( t ) { - var x = new Uint64( 3.14 ); - t.strictEqual( x.value, 3.140625, 'returns expected value' ); + var x = new Uint64( 3 ); + t.strictEqual( x.value.toString(), '3', 'returns expected value' ); t.end(); }); */ +tape( 'if provided a BigInt, the constructor stores the lower 64 bits', function test( t ) { + var x; + + if ( !hasBigIntSupport() ) { + t.pass( 'environment does not support BigInt' ); + t.end(); + return; + } + x = new Uint64( BigInt( '18446744073709551616' ) ); + t.strictEqual( x.toString(), '0', 'returns expected value' ); + t.end(); +}); + +tape( 'if provided a BigInt and a high-low flag, the constructor stores a Uint32Array', function test( t ) { + var x; + + if ( !hasBigIntSupport() ) { + t.pass( 'environment does not support BigInt' ); + t.end(); + return; + } + x = new Uint64( BigInt( '18446744073709551616' ), true ); + t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 0, 0 ], 'returns expected value' ); + t.end(); +}); + +tape( 'if provided a Uint32Array of length 2 and no high-low flag, the constructor stores the expected numeric value', function test( t ) { + var x; + + x = new Uint64( new Uint32Array( [ 1, 2 ] ) ); + t.strictEqual( x.toString(), '4294967298', 'returns expected value' ); + t.end(); +}); + +tape( 'if provided a Uint32Array of length 2 and a high-low flag, the constructor stores a Uint32Array value', function test( t ) { + var x; + + x = new Uint64( new Uint32Array( [ 1, 2 ] ), true ); + t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 2 ], 'returns expected value' ); + t.end(); +}); + +tape( 'if provided a Uint32Array which does not have length 2, the constructor throws an error', function test( t ) { + t.throws( badValue, TypeError, 'throws an error' ); + t.end(); + + function badValue() { + var x = new Uint64( new Uint32Array( 1 ) ); // eslint-disable-line no-unused-vars + } +}); + +tape( 'if provided an array of length 2 and no high-low flag, the constructor stores the expected numeric value', function test( t ) { + var x; + + x = new Uint64( [ 1, 2 ] ); + t.strictEqual( x.toString(), '4294967298', 'returns expected value' ); + t.end(); +}); + +tape( 'if provided an array of length 2 and a high-low flag, the constructor stores a Uint32Array value', function test( t ) { + var x; + + x = new Uint64( [ 1, 2 ], true ); + t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 2 ], 'returns expected value' ); + t.end(); +}); + +tape( 'if provided an array of length 2 with float values, the constructor coerces words to uint32', function test( t ) { + var x; + + x = new Uint64( [ 1.9, 2.1 ], true ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 2 ], 'returns expected value' ); + t.end(); +}); + +tape( 'if provided an array with a length not equal to 2, the constructor throws an error', function test( t ) { + t.throws( badValue, TypeError, 'throws an error' ); + t.end(); + + function badValue() { + var x = new Uint64( [ 1 ] ); // eslint-disable-line no-unused-vars + } +}); + +tape( 'if provided an array containing non-number elements, the constructor throws an error', function test( t ) { + t.throws( badValue, TypeError, 'throws an error' ); + t.end(); + + function badValue() { + var x = new Uint64( [ '1', 2 ] ); // eslint-disable-line no-unused-vars + } +}); + +tape( 'if provided an array containing out-of-range numbers, the constructor throws an error', function test( t ) { + t.throws( badValue, TypeError, 'throws an error' ); + t.end(); + + function badValue() { + var x = new Uint64( [ -1, 2 ] ); // eslint-disable-line no-unused-vars + } +}); + +tape( 'if provided a valid integer-valued string and no high-low flag, the constructor stores the expected numeric value', function test( t ) { + var x; + + x = new Uint64( '123456' ); + t.strictEqual( x.toString(), '123456', 'returns expected value' ); + t.end(); +}); + +tape( 'if provided an invalid string and no high-low flag, the constructor throws an error', function test( t ) { + t.throws( badValue, TypeError, 'throws an error' ); + t.end(); + + function badValue() { + var x = new Uint64( 'beep boop' ); // eslint-disable-line no-unused-vars + } +}); + +tape( 'if provided a string and a high-low flag, the constructor stores the same numeric value as in BigInt mode', function test( t ) { + var x; + + x = new Uint64( '123456', true ); + t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 0, 123456 ], 'returns expected value' ); + t.strictEqual( x.toString(), '123456', 'returns expected value' ); + + x = new Uint64( '4294967296', true ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 0 ], 'returns expected value' ); + t.strictEqual( x.toString(), '4294967296', 'returns expected value' ); + + t.throws( badValue, TypeError, 'throws an error for invalid string' ); + t.end(); + + function badValue() { + var x = new Uint64( 'beep boop', true ); // eslint-disable-line no-unused-vars + } +}); + +tape( 'if provided a valid number and a high-low flag, the constructor stores high-low words', function test( t ) { + var x; + + x = new Uint64( 4294967301, true ); + t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 5 ], 'returns expected value' ); + t.end(); +}); + +tape( 'if provided an invalid number, the constructor throws an error', function test( t ) { + var values; + var i; + + values = [ + -1, + 3.14, + Number.MAX_SAFE_INTEGER + 1 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided '+values[i] ); + } + t.end(); + + function badValue( value ) { + return function badValue() { + var x = new Uint64( value ); // eslint-disable-line no-unused-vars + }; + } +}); + tape( 'the constructor returns an instance which supports serializing an instance as a string', function test( t ) { var x; x = new Uint64( 5 ); t.strictEqual( x.toString(), '5', 'returns expected value' ); - // TODO: should we support base conversion in toString? - /* + x = new Uint64( [ 1, 0 ], true ); + t.strictEqual( x.toString( 16 ), '100000000', 'returns expected value' ); + + x = new Uint64( [ 0, 15 ], true ); + t.strictEqual( x.toString( 16 ), 'f', 'returns expected value' ); + + x = new Uint64( [ 0, 5 ], true ); + t.strictEqual( x.toString( 10 ), '5', 'returns expected value' ); + x = new Uint64( 255 ); t.strictEqual( x.toString(16), 'ff', 'returns expected value' ); - */ + t.end(); }); @@ -159,6 +344,12 @@ tape( 'the constructor returns an instance which supports serializing an instanc t.strictEqual( JSON.stringify( x ), JSON.stringify( expected ), 'returns expected value' ); // TODO: test array format of toJSON if applicable after review + x = new Uint64( [ 1, 2 ], true ); + expected = { + 'type': 'Uint64', + 'value': [ 1, 2 ] + }; + t.deepEqual( x.toJSON(), expected, 'returns expected value' ); t.end(); }); @@ -172,12 +363,28 @@ tape( 'the constructor returns an instance which supports converting an instance x = new Uint64( [ 1, 0 ] ); t.strictEqual( x.valueOf(), 4294967296, 'returns expected value' ); + x = new Uint64( [ 1, 0 ], true ); + t.strictEqual( x.valueOf(), -1, 'returns expected value' ); + x = new Uint64( 0 ); t.strictEqual( x.valueOf(), 0, 'returns expected value' ); t.end(); }); +tape( 'if an environment supports `Symbol.toPrimitive`, instances expose a toPrimitive method', function test( t ) { + var x; + + if ( !hasToPrimSymSupport() ) { + t.pass( 'environment does not support Symbol.toPrimitive' ); + t.end(); + return; + } + x = new Uint64( 5 ); + t.strictEqual( x[ ToPrimitiveSymbol ]( 'number' ), 5, 'returns expected value' ); + t.end(); +}); + // TODO: we discussed that direct operations will not be supported without the functional utils // And should we actually remove the ToPrimitive function? /* @@ -216,5 +423,3 @@ tape( 'if an environment supports `Symbol.toPrimitive`, the constructor returns t.end(); }); */ - -// TODO: add more tests like truncation, array size check, etc From 80975523cbd7a21a11cccd3e7a55967a81a99952 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 21:54:51 +0600 Subject: [PATCH 22/29] fix: fix unnecessary leading zeros in toString() --- .../number/uint64/ctor/lib/tostring.js | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js index 05711889b750..0b55aeb6cc11 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js @@ -27,7 +27,8 @@ var lpad = require( '@stdlib/string/left-pad' ); // Helper constants for toString base conversion -var TWO_16 = 1 << 16; +var TWO_16 = 0x10000; +var TWO_32 = 0x100000000; var POWERMAP = { '2': { @@ -179,7 +180,7 @@ var POWERMAP = { * Serializes an unsigned 64-bit integer as a string in the specified base. * * @private -* @param {number} base - The radix (base) to use for string conversion +* @param {number} radix - The radix (base) to use for string conversion * @returns {string} The serialized unsigned 64-bit integer as a string. * * **Note** @@ -188,23 +189,26 @@ var POWERMAP = { * The divisor values are chosen to be close to powers of 2^32 for each supported base, which is an unusual but efficient approach for chunked conversion. * The function pads the lower chunk with leading zeros to ensure correct digit alignment. */ -function toString( base ) { // eslint-disable-line stdlib/no-redeclare +function toString( radix ) { // eslint-disable-line stdlib/no-redeclare // eslint-disable-next-line no-undefined - if ( base === undefined ) { - base = 10; + if ( radix === undefined ) { + radix = 10; } // TODO: validate base range (between 2 and 36) if ( typeof this.value === 'bigint' ) { - return this.value.toString( base ); + return this.value.toString( radix ); } - var qr = divmod( this.value, POWERMAP[ base ].divisor ); - var sq = qr[ 0 ].toString( base ); - var sr = qr[ 1 ].toString( base ); + var qr = chunkedDivMod( this.value, POWERMAP[ radix ].divisor ); + var sq = qr[ 0 ].toString( radix ); + var sr = qr[ 1 ].toString( radix ); if ( sq === '0' ) { sq = ''; } - sr = lpad( sr, POWERMAP[ base ].power, '0' ); + else { + sr = lpad( sr, POWERMAP[ radix ].power, '0' ); + } + return sq + sr; } @@ -213,14 +217,14 @@ function toString( base ) { // eslint-disable-line stdlib/no-redeclare * * @private * @param {Uint32Array|Array} words - [high, low] 32-bit words -* @param {number} divisor - positive integer close to `2^32` +* @param {number} divisor - positive integer close to `2^32` (actually works for 2^11 to 2^37) * @returns {Array} [ quotient, remainder ] * * @example -* var x = divmod( [ 0, 5 ] ); -* // returns [ 0, NaN ] +* var x = chunkedDivMod( [ 1, 0 ], 1e9 ); +* // returns [ 4, 294967296 ] */ -function divmod( words, divisor ) { +function chunkedDivMod( words, divisor ) { var hi = words[0] >>> 0; var lo = words[1] >>> 0; @@ -228,7 +232,7 @@ function divmod( words, divisor ) { var rem = hi - ( divisor * quo ); var qrd; - if (divisor === 0x100000000) { + if (divisor === TWO_32) { return [ hi, lo ]; } From cef9e28f23b84f0f3350bae3c21a893460ea9706 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 21:55:17 +0600 Subject: [PATCH 23/29] feat: implement string parsing in Uint64 constructor --- .../@stdlib/number/uint64/ctor/lib/main.js | 62 +++++++++++++++++-- 1 file changed, 58 insertions(+), 4 deletions(-) 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 6643bf1216c5..8af8c5fe306a 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -30,11 +30,14 @@ var hasBigIntSupport = require( '@stdlib/assert/has-bigint-support' ); var hasToPrimitiveSymbolSupport = require( '@stdlib/assert/has-to-primitive-symbol-support' ); // eslint-disable-line id-length var isArray = require( '@stdlib/assert/is-array' ); var isBigInt = require( '@stdlib/assert/is-bigint' ); +var isNan = require( '@stdlib/assert/is-nan' ); var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; var isString = require( '@stdlib/assert/is-string' ); var isUint32Array = require( '@stdlib/assert/is-uint32array' ); +var max = require( '@stdlib/math/base/special/max' ); var setEnumerableReadOnly = require( '@stdlib/utils/define-read-only-property' ); var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var trim = require( '@stdlib/string/trim' ); var asBigUint64 = require( './asbiguint64.js' ); var toStr = require( './tostring.js' ); var toJSON = require( './tojson.js' ); @@ -63,8 +66,14 @@ var TWO_32 = 0x100000000; * // returns */ function Uint64( value, useHighLow ) { + // TODO: should we optimize number of vars? var high; var low; + var tmp; + var ih; + var il; + var i; + useHighLow |= !hasBigIntSupport(); if ( !( this instanceof Uint64 ) ) { @@ -123,17 +132,62 @@ function Uint64( value, useHighLow ) { } } else if ( isString( value ) ) { + // TODO: verify same parsing behavior as BigInt if ( useHighLow ) { - // TODO: decompose into high low - setEnumerableReadOnly( this, 'value', new Uint32Array( [ 0, 0 ] ) ); + value = trim( value ); + if ( value.match( /^0x/i ) ) { + il = max( 2, value.length - 8 ); + ih = max( 2, value.length - 16 ); + high = Number( '0x' + value.slice( ih, il ) ); + low = Number( '0x' + value.slice( il ) ); + } + else if ( value.match( /^0o/i ) ) { + il = max( 2, value.length - 16 ); + ih = max( 2, value.length - 32 ); + high = Number( '0o' + value.slice( ih, il ) ); + low = Number( '0o' + value.slice( il ) ); + } + else if ( value.match( /^0b/i ) ) { + il = max( 2, value.length - 32 ); + ih = max( 2, value.length - 64 ); + high = Number( '0b' + value.slice( ih, il ) ); + low = Number( '0b' + value.slice( il ) ); + } + else if ( value.match( /[^0-9]/ ) ) { + high = low = NaN; + } + else { + i = ( value.length % 6 ) || 6; // processes the first chunk such as the remaining chunks are all evenly sized (6digit) + if ( i + 6 <= 9 ) { // takes big chunk when possible + i += 6; + } + high = 0; + low = Number( value.slice( 0, i ) ); + for ( ; i < value.length; i += 6 ) { + tmp = Number( value.slice( i, i + 6 ) ); + low = ( low * 1e6 ) + tmp; + tmp = ( low / TWO_32 ) >>> 0; + low -= tmp * TWO_32; + high = ( high * 1e6 ) + tmp; + tmp = ( high / TWO_32 ) >>> 0; + high -= tmp * TWO_32; + } + } + + if ( !isNaN( high ) && !isNan( low ) ) { + value = new Uint32Array( [ high, low ] ); + } + else { + throw new TypeError( format( 'invalid argument. Could not convert string to Uint64. Value: `%s`.', value ) ); + } } else { try { - setEnumerableReadOnly( this, 'value', asBigUint64( BigInt( value ) ) ); + value = asBigUint64( BigInt( value ) ); } // eslint-disable-next-line no-unused-vars catch ( error ) { - throw new TypeError( format( 'invalid argument. Could not convert string to BigInt. Value: `%s`.', value ) ); + throw new TypeError( format( 'invalid argument. Could not convert string to Uint64. Value: `%s`.', value ) ); } } } From 85a93789e5bd005575efe643bd3dd5617ea5a3f9 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 14 Mar 2026 22:23:00 +0600 Subject: [PATCH 24/29] test: add tests for parsing prefixed and whitespace-padded strings in Uint64 constructor --- .../@stdlib/number/uint64/ctor/test/test.js | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) 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 377047a46c79..5837078e298d 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -280,6 +280,33 @@ tape( 'if provided a string and a high-low flag, the constructor stores the same } }); +tape( 'if provided prefixed or whitespace-padded strings and a high-low flag, the constructor parses the expected numeric value', function test( t ) { + // TODO: generated tests, to be refined + var x; + + x = new Uint64( ' 123456 ', true ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 0, 123456 ], 'parses whitespace-padded decimal string' ); + t.strictEqual( x.toString(), '123456', 'returns expected decimal string' ); + + x = new Uint64( '1234567890123', true ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 287, 1912276171 ], 'parses chunked decimal string' ); + t.strictEqual( x.toString(), '1234567890123', 'preserves decimal numeric value' ); + + x = new Uint64( '0x123456789abcdef0', true ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 0x12345678, 0x9abcdef0 ], 'parses hexadecimal string' ); + t.strictEqual( x.toString( 16 ), '123456789abcdef0', 'returns expected hexadecimal string' ); + + x = new Uint64( '0o10000000000000000', true ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 0 ], 'parses octal string' ); + t.strictEqual( x.toString(), '4294967296', 'returns expected decimal value for octal input' ); + + x = new Uint64( '0b100000000000000000000000000000000', true ); + t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 0 ], 'parses binary string' ); + t.strictEqual( x.toString(), '4294967296', 'returns expected decimal value for binary input' ); + + t.end(); +}); + tape( 'if provided a valid number and a high-low flag, the constructor stores high-low words', function test( t ) { var x; From 2945c3208acfb3d34b0434c39f2138d4a53a6999 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Tue, 17 Mar 2026 06:36:24 +0600 Subject: [PATCH 25/29] fix: update TODO comments for clarity and valueOf implementation --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: passed - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed --- --- .../number/uint64/ctor/benchmark/benchmark.js | 2 +- .../@stdlib/number/uint64/ctor/docs/types/index.d.ts | 4 ++-- .../@stdlib/number/uint64/ctor/lib/main.js | 11 +++++++---- .../@stdlib/number/uint64/ctor/lib/valueof.js | 5 +++-- .../@stdlib/number/uint64/ctor/test/test.js | 12 ++++++------ 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js b/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js index 6bd879e1b100..49c9acc899be 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/benchmark/benchmark.js @@ -49,7 +49,7 @@ bench( pkg, function benchmark( b ) { b.end(); }); -// TODO: because `value` should be private? +// TODO: disabled because `value` should be private? /* bench( format( '%s::get:value', pkg ), function benchmark( b ) { diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts index d88e404c90ed..06f0e5be03c4 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts @@ -33,7 +33,7 @@ declare class Uint64 { * // returns */ constructor( value: number | string | Array | Uint32Array | BigInt ); - // TODO: do we need to import Uint32Array and BigInt here as well? + // TODO: do we need to import Uint32Array and BigInt here in this file as well? /** * Read-only property returning the value. @@ -41,7 +41,7 @@ declare class Uint64 { * @returns value */ // readonly value: number; - // TODO: because private + // TODO: disabled because should be private, will remove/update after review /** * Size (in bytes) of the underlying value. 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 8af8c5fe306a..0b0a9f67e960 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -82,9 +82,8 @@ function Uint64( value, useHighLow ) { // TODO: current implementation uses either BigInt or Uint32Array for the internal representation // Are there other better alternative instead of Uint32Array? How is plain old number array? - // Or an object with high and low props? - - // TODO: make the `value` property private + // Or an object with properties named high, low and big + // - where high low is always present and big is the bigint representation when applicable if ( isBigInt( value ) ) { value = asBigUint64( value ); @@ -93,7 +92,7 @@ function Uint64( value, useHighLow ) { low = Number( value & BigInt( MAX_UINT32 ) ); value = new Uint32Array( [ high, low ] ); - // TODO: should we use value[0] = high, value[1] = low instead to avoid the intermediate array allocation? + // TODO: should we use value[0] = high, value[1] = low instead to avoid the intermediate [high, low] array allocation? } } else if ( isUint32Array( value ) ) { @@ -157,6 +156,7 @@ function Uint64( value, useHighLow ) { high = low = NaN; } else { + // chunked parsing for decimal string i = ( value.length % 6 ) || 6; // processes the first chunk such as the remaining chunks are all evenly sized (6digit) if ( i + 6 <= 9 ) { // takes big chunk when possible i += 6; @@ -210,6 +210,9 @@ function Uint64( value, useHighLow ) { throw new TypeError( format( 'invalid argument. Must provide a number or string or Array or Uint32Array or BigInt. Value: `%s`.', value ) ); } + // TODO: make the `value` property / whatever internal representation private + // I guess it's not technically possible to make it truely private in our implementation because of the current of structure of the package? + // using es6 class is not permitted and the other option is closure based encapsulation but then we'll have to move the other member functions inside the constructor setEnumerableReadOnly( this, 'value', value ); return this; } diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js index 87f538b63f2f..7393f15f6a1b 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js @@ -23,6 +23,8 @@ var Number = require( '@stdlib/number/ctor' ); +var TWO_32 = 0x100000000; + // MAIN // @@ -37,8 +39,7 @@ function valueOf() { // eslint-disable-line stdlib/no-redeclare return Number( this.value ); } - // TODO: implement conversion to number - return -1; + return ( this.value[ 0 ] * TWO_32 ) + this.value[ 1 ]; } 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 5837078e298d..652003510974 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -387,14 +387,14 @@ tape( 'the constructor returns an instance which supports converting an instance x = new Uint64( 5 ); t.strictEqual( x.valueOf(), 5, 'returns expected value' ); - x = new Uint64( [ 1, 0 ] ); - t.strictEqual( x.valueOf(), 4294967296, 'returns expected value' ); + x = new Uint64( [ 0xffffffff, 0xffffffff ] ); + t.strictEqual( x.valueOf(), 18446744073709552000, 'returns expected value' ); - x = new Uint64( [ 1, 0 ], true ); - t.strictEqual( x.valueOf(), -1, 'returns expected value' ); + x = new Uint64( [ 0xffffffff, 0xffffffff ], true ); + t.strictEqual( x.valueOf(), 18446744073709552000, 'returns expected value' ); - x = new Uint64( 0 ); - t.strictEqual( x.valueOf(), 0, 'returns expected value' ); + x = new Uint64( Number.MAX_SAFE_INTEGER ); + t.strictEqual( x.valueOf(), Number.MAX_SAFE_INTEGER, 'returns expected value' ); t.end(); }); From aae8b275242314e7976a4c91901ed2e93572d5b0 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Thu, 19 Mar 2026 11:17:25 +0600 Subject: [PATCH 26/29] refactor: refactor parsing logic out of Uint64 constructor and more --- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed --- --- .../number/uint64/ctor/lib/gethighword.js | 48 ++++ .../number/uint64/ctor/lib/getlowword.js | 49 ++++ .../@stdlib/number/uint64/ctor/lib/main.js | 215 ++++++++---------- .../number/uint64/ctor/lib/parseuint64dw.js | 119 ++++++++++ .../number/uint64/ctor/lib/tobigint.js | 39 ++++ .../@stdlib/number/uint64/ctor/lib/tojson.js | 11 +- .../number/uint64/ctor/lib/tostring.js | 115 +++++----- .../@stdlib/number/uint64/ctor/lib/valueof.js | 11 +- 8 files changed, 422 insertions(+), 185 deletions(-) create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/gethighword.js create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/getlowword.js create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/parseuint64dw.js create mode 100644 lib/node_modules/@stdlib/number/uint64/ctor/lib/tobigint.js diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/gethighword.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/gethighword.js new file mode 100644 index 000000000000..c760c44cb9ab --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/gethighword.js @@ -0,0 +1,48 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var BigInt = require( '@stdlib/bigint/ctor' ); +var Number = require( '@stdlib/number/ctor' ); + + +// MAIN // + +/** +* Returns the high 32-bit word of an unsigned 64-bit integer number. +* +* @private +* @returns {number} 32-bit unsigned integer +* +*/ +function getHighWord() { + /* eslint-disable no-invalid-this */ + if ( typeof this._raw === 'bigint' ) { + return Number( this._raw >> BigInt( 32 ) ); + } + + return this._raw[ 0 ]; +} + + +// EXPORTS // + +module.exports = getHighWord; diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/getlowword.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/getlowword.js new file mode 100644 index 000000000000..a2dd998d01e8 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/getlowword.js @@ -0,0 +1,49 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var BigInt = require( '@stdlib/bigint/ctor' ); +var Number = require( '@stdlib/number/ctor' ); +var UINT32_MAX = require( '@stdlib/constants/uint32/max' ); + + +// MAIN // + +/** +* Returns the low 32-bit word of an unsigned 64-bit integer number. +* +* @private +* @returns {number} 32-bit unsigned integer +* +*/ +function getLowWord() { + /* eslint-disable no-invalid-this */ + if ( typeof this._raw === 'bigint' ) { + return Number( this._raw & BigInt( UINT32_MAX ) ); + } + + return this._raw[ 1 ]; +} + + +// EXPORTS // + +module.exports = getLowWord; 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 0b0a9f67e960..460cc05e0748 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/main.js @@ -1,4 +1,3 @@ -/* eslint-disable max-len */ /** * @license Apache-2.0 * @@ -17,35 +16,40 @@ * limitations under the License. */ +/* eslint-disable max-len */ + 'use strict'; // MODULES // var BigInt = require( '@stdlib/bigint/ctor' ); var Number = require( '@stdlib/number/ctor' ); -var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); +var UINT32_MAX = require( '@stdlib/constants/uint32/max' ); var Uint32Array = require( '@stdlib/array/uint32' ); var format = require( '@stdlib/string/format' ); var hasBigIntSupport = require( '@stdlib/assert/has-bigint-support' ); -var hasToPrimitiveSymbolSupport = require( '@stdlib/assert/has-to-primitive-symbol-support' ); // eslint-disable-line id-length var isArray = require( '@stdlib/assert/is-array' ); var isBigInt = require( '@stdlib/assert/is-bigint' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; var isNan = require( '@stdlib/assert/is-nan' ); var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; var isString = require( '@stdlib/assert/is-string' ); var isUint32Array = require( '@stdlib/assert/is-uint32array' ); -var max = require( '@stdlib/math/base/special/max' ); -var setEnumerableReadOnly = require( '@stdlib/utils/define-read-only-property' ); var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); -var trim = require( '@stdlib/string/trim' ); var asBigUint64 = require( './asbiguint64.js' ); -var toStr = require( './tostring.js' ); +var getHighWord = require( './gethighword.js' ); +var getLowWord = require( './getlowword.js' ); +var parseUint64dw = require( './parseuint64dw.js' ); +var toBigInt = require( './tobigint.js' ); var toJSON = require( './tojson.js' ); +var toString = require( './tostring.js' ); // eslint-disable-line stdlib/no-redeclare var valueOf = require( './valueof.js' ); // eslint-disable-line stdlib/no-redeclare -// TODO: should we add asm type annotations aggressively? -var MAX_UINT32 = 0xffffffff; + +// VARIABLES // + var TWO_32 = 0x100000000; +var hasBigInt = hasBigIntSupport(); // MAIN // @@ -55,50 +59,31 @@ var TWO_32 = 0x100000000; * * @constructor * @param {number|string|Array|Uint32Array|BigInt} value - numeric value or high low words or BigInt -* TODO: Which ones should we keep and discard? Should we support any arraylike argument? -* @param {boolean} useHighLow - use double word Uint32Array representation -* @throws {TypeError} must invoke using the `new` keyword -* @throws {TypeError} value must be a number or bla bla bla // TODO: update after review +* @throws {TypeError} * @returns {Uint64} Unsigned 64-bit integer * * @example // TODO: add more example * var x = new Uint64( 5 ); * // returns */ -function Uint64( value, useHighLow ) { - // TODO: should we optimize number of vars? - var high; - var low; +function Uint64( value ) { + var raw; var tmp; - var ih; - var il; - var i; - - useHighLow |= !hasBigIntSupport(); if ( !( this instanceof Uint64 ) ) { throw new TypeError( 'invalid invocation. Constructor must be called with the `new` keyword.' ); } - // TODO: current implementation uses either BigInt or Uint32Array for the internal representation - // Are there other better alternative instead of Uint32Array? How is plain old number array? - // Or an object with properties named high, low and big - // - where high low is always present and big is the bigint representation when applicable - if ( isBigInt( value ) ) { - value = asBigUint64( value ); - if ( useHighLow ) { - high = Number( value >> BigInt( 32 ) ); - low = Number( value & BigInt( MAX_UINT32 ) ); - value = new Uint32Array( [ high, low ] ); - - // TODO: should we use value[0] = high, value[1] = low instead to avoid the intermediate [high, low] array allocation? - } + raw = asBigUint64( value ); } else if ( isUint32Array( value ) ) { if ( value.length === 2 ) { - if ( !useHighLow ) { - value = ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ); + if ( hasBigInt ) { + raw = ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ); + } + else { + raw = value; // TODO: should we copy it instead? } } else { @@ -107,23 +92,16 @@ function Uint64( value, useHighLow ) { } else if ( isArray( value ) ) { if ( value.length === 2 ) { - if ( typeof value[ 0 ] === 'number' && typeof value[ 1 ] === 'number' ) { - if ( value[ 0 ] >= 0 && value[ 0 ] <= MAX_UINT32 && value[ 1 ] >= 0 && value[ 1 ] <= MAX_UINT32 ) { - value[ 0 ] >>>= 0; - value[ 1 ] >>>= 0; - if ( useHighLow ) { - value = new Uint32Array( value ); - } - else { - value = ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ); - } + if ( isInteger( value[ 0 ] ) && isInteger( value[ 1 ] ) && value[ 0 ] >= 0 && value[ 0 ] <= UINT32_MAX && value[ 1 ] >= 0 && value[ 1 ] <= UINT32_MAX ) { + if ( hasBigInt ) { + raw = ( BigInt( value[ 0 ] ) << BigInt( 32 ) ) | BigInt( value[ 1 ] ); } else { - throw new TypeError( format( 'invalid argument. Provided numbers must be between 0 and %s. Value: `%s`.', MAX_UINT32, value ) ); + raw = new Uint32Array( value ); } } else { - throw new TypeError( format( 'invalid argument. Provided array must contain only elements of type number. Value: `%s`.', value ) ); + throw new TypeError( format( 'invalid argument. Provided array must contain only integer values between 0 and %s. Value: `%s`.', UINT32_MAX, value ) ); } } else { @@ -131,75 +109,45 @@ function Uint64( value, useHighLow ) { } } else if ( isString( value ) ) { - // TODO: verify same parsing behavior as BigInt - if ( useHighLow ) { - value = trim( value ); - if ( value.match( /^0x/i ) ) { - il = max( 2, value.length - 8 ); - ih = max( 2, value.length - 16 ); - high = Number( '0x' + value.slice( ih, il ) ); - low = Number( '0x' + value.slice( il ) ); - } - else if ( value.match( /^0o/i ) ) { - il = max( 2, value.length - 16 ); - ih = max( 2, value.length - 32 ); - high = Number( '0o' + value.slice( ih, il ) ); - low = Number( '0o' + value.slice( il ) ); + if ( value[ 0 ] === '-' ) { + throw new TypeError( format( 'invalid argument. Provided value must be non-negative. Value: `%s`.', value ) ); + } + + if ( hasBigInt ) { + try { + raw = asBigUint64( BigInt( value ) ); } - else if ( value.match( /^0b/i ) ) { - il = max( 2, value.length - 32 ); - ih = max( 2, value.length - 64 ); - high = Number( '0b' + value.slice( ih, il ) ); - low = Number( '0b' + value.slice( il ) ); + catch ( error ) { // eslint-disable-line no-unused-vars + throw new TypeError( format( 'invalid argument. Could not convert string to Uint64. Value: `%s`.', value ) ); } - else if ( value.match( /[^0-9]/ ) ) { - high = low = NaN; + } + else { + if ( value[ 0 ] === '+' ) { + tmp = value.slice( 1 ); } else { - // chunked parsing for decimal string - i = ( value.length % 6 ) || 6; // processes the first chunk such as the remaining chunks are all evenly sized (6digit) - if ( i + 6 <= 9 ) { // takes big chunk when possible - i += 6; - } - high = 0; - low = Number( value.slice( 0, i ) ); - for ( ; i < value.length; i += 6 ) { - tmp = Number( value.slice( i, i + 6 ) ); - low = ( low * 1e6 ) + tmp; - tmp = ( low / TWO_32 ) >>> 0; - low -= tmp * TWO_32; - high = ( high * 1e6 ) + tmp; - tmp = ( high / TWO_32 ) >>> 0; - high -= tmp * TWO_32; - } + tmp = value; } - if ( !isNaN( high ) && !isNan( low ) ) { - value = new Uint32Array( [ high, low ] ); + tmp = parseUint64dw( tmp ); + + if ( !isNaN( tmp[ 0 ] ) && !isNan( tmp[ 1 ] ) ) { + raw = new Uint32Array( tmp ); } else { throw new TypeError( format( 'invalid argument. Could not convert string to Uint64. Value: `%s`.', value ) ); } } - else { - try { - value = asBigUint64( BigInt( value ) ); - } - // eslint-disable-next-line no-unused-vars - catch ( error ) { - throw new TypeError( format( 'invalid argument. Could not convert string to Uint64. Value: `%s`.', value ) ); - } - } } else if ( isNumber( value ) ) { if ( value >= 0 && Number.isSafeInteger( value ) ) { - if ( useHighLow ) { - high = ( value / TWO_32 ) >>> 0; - low = value >>> 0; - value = new Uint32Array( [ high, low ] ); + if ( hasBigInt ) { + raw = asBigUint64( BigInt( value ) ); } else { - value = asBigUint64( BigInt( value ) ); + raw = new Uint32Array( 2 ); + raw[ 0 ] = ( value / TWO_32 ) >>> 0; + raw[ 1 ] = value >>> 0; } } else { @@ -210,10 +158,7 @@ function Uint64( value, useHighLow ) { throw new TypeError( format( 'invalid argument. Must provide a number or string or Array or Uint32Array or BigInt. Value: `%s`.', value ) ); } - // TODO: make the `value` property / whatever internal representation private - // I guess it's not technically possible to make it truely private in our implementation because of the current of structure of the package? - // using es6 class is not permitted and the other option is closure based encapsulation but then we'll have to move the other member functions inside the constructor - setEnumerableReadOnly( this, 'value', value ); + setReadOnly( this, '_raw', raw ); return this; } @@ -281,7 +226,7 @@ setReadOnly( Uint64.prototype, 'BYTES_PER_ELEMENT', 8 ); * // returns '100000000001' * */ -setReadOnly( Uint64.prototype, 'toString', toStr ); +setReadOnly( Uint64.prototype, 'toString', toString ); /** * Serializes an unsigned 64-bit integer number as a JSON object. @@ -298,8 +243,8 @@ setReadOnly( Uint64.prototype, 'toString', toStr ); * @example * var x = new Uint64( 5 ); * -* var obj = x.toJSON(); -* // returns { 'type': 'Uint64', 'value': '5' } +* var y = x.toJSON(); +* // returns { 'type': 'Uint64', 'high': 0, 'low': 5 } */ setReadOnly( Uint64.prototype, 'toJSON', toJSON ); @@ -320,28 +265,60 @@ setReadOnly( Uint64.prototype, 'toJSON', toJSON ); setReadOnly( Uint64.prototype, 'valueOf', valueOf ); /** -* Returns the primitive value of an unsigned 64-bit integer number. +* Returns the high 32-bit word of an unsigned 64-bit integer number. * -* @name toPrimitive +* @name getHighWord * @memberof Uint64.prototype * @type {Function} -* @param {string} hint - conversion hint -* @returns {number} primitive value +* @returns {number} 32-bit unsigned integer +* +* @example +* +* var x = new Uint64( [ 1234, 5678 ] ); +* +* var y = x.getHighWord(); +* // returns 1234.0 +*/ +setReadOnly( Uint64.prototype, 'getHighWord', getHighWord ); + +/** +* Returns the low 32-bit word of an unsigned 64-bit integer number. +* +* @name getLowWord +* @memberof Uint64.prototype +* @type {Function} +* @returns {number} 32-bit unsigned integer +* +* @example +* +* var x = new Uint64( [ 1234, 5678 ] ); +* +* var y = x.getLowWord(); +* // returns 5678.0 +*/ +setReadOnly( Uint64.prototype, 'getLowWord', getLowWord ); + +/** +* Converts an unsigned 64-bit integer number to a BigInt. +* +* @name toBigInt +* @memberof Uint64.prototype +* @type {Function} +* @returns {BigInt} BigInt value * * @example -* var hasSymbol = require( '@stdlib/assert/has-to-primitive-symbol-support' ); -* var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); +* var hasBigInt = require( '@stdlib/assert/has-bigint-support' ); * * var x = new Uint64( 5 ); * * var v; -* if ( hasSymbol() ) { -* v = x[ ToPrimitiveSymbol ]( 'number' ); +* if ( hasBigInt() ) { +* v = x.toBigInt(); * // returns 5.0 * } */ -if ( hasToPrimitiveSymbolSupport() ) { - setReadOnly( Uint64.prototype, ToPrimitiveSymbol, valueOf ); +if ( hasBigInt ) { + setReadOnly( Uint64.prototype, 'toBigInt', toBigInt ); } diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/parseuint64dw.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/parseuint64dw.js new file mode 100644 index 000000000000..3d151a0f75c0 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/parseuint64dw.js @@ -0,0 +1,119 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var Number = require( '@stdlib/number/ctor' ); +var max = require( '@stdlib/math/base/special/max' ); +var trim = require( '@stdlib/string/trim' ); + + +// VARIABLES // + +var TWO_32 = 0x100000000; +var RE_HEX = /^0x/i; +var RE_OCT = /^0o/i; +var RE_BIN = /^0b/i; +var RE_INV = /[^0-9]/; // Invalid decimal integer + + +// MAIN // + +/** +* Parses an arbitrary-length string representation of an unsigned integer and converts to double word representation of unsigned 64 bit integer. +* +* @private +* @param {string} value - string representation of an unsigned integer +* @returns {Uint32Array} Unsigned 64-bit integer as high and low words +* +* @example +* var x = parseUint64dw( '0xffffffff0000ffff' ); +* // returns [ 4294967295, 65535 ] +* +* x = parseUint64dw( '0x1ffffffff0000ffff' ); +* // returns [ 4294967295, 65535 ] +* +* x = parseUint64dw( '0xffff' ); +* // returns [ 0, 65535 ] +* +* x = parseUint64dw( '0o100' ); +* // returns [ 0, 64 ] +* +* x = parseUint64dw( '0b100' ); +* // returns [ 0, 4 ] +* +* x = parseUint64dw( '4294967296' ); +* // returns [ 1, 0 ] +*/ +function parseUint64dw( value ) { + var high; + var low; + var tmp; + var j; + var i; + + value = trim( value ); + if ( RE_HEX.test( value ) ) { + j = max( 2, value.length - 8 ); + i = max( 2, value.length - 16 ); + high = Number( '0x0' + value.slice( i, j ) ); + low = Number( '0x' + value.slice( j ) ); + } + else if ( RE_OCT.test( value ) ) { + j = max( 2, value.length - 16 ); + i = max( 2, value.length - 32 ); + high = Number( '0o0' + value.slice( i, j ) ); + low = Number( '0o' + value.slice( j ) ); + } + else if ( RE_BIN.test( value ) ) { + j = max( 2, value.length - 32 ); + i = max( 2, value.length - 64 ); + high = Number( '0b0' + value.slice( i, j ) ); + low = Number( '0b' + value.slice( j ) ); + } + else if ( RE_INV.test( value ) ) { + high = low = NaN; + } + else { + // Chunked parsing for decimal string + i = ( value.length % 6 ) || 6; // Processes the first chunk such as the remaining chunks are all evenly sized (6digit) + if ( i + 6 <= 9 ) { // Takes big chunk when possible + i += 6; + } + high = 0; + low = Number( value.slice( 0, i ) ); + for ( ; i < value.length; i += 6 ) { + tmp = Number( value.slice( i, i + 6 ) ); + low = ( low * 1e6 ) + tmp; + tmp = ( low / TWO_32 ) >>> 0; + low -= tmp * TWO_32; + high = ( high * 1e6 ) + tmp; + tmp = ( high / TWO_32 ) >>> 0; + high -= tmp * TWO_32; + } + } + + return [ high, low ]; +} + + +// EXPORTS // + +module.exports = parseUint64dw; diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tobigint.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tobigint.js new file mode 100644 index 000000000000..419992e0f880 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tobigint.js @@ -0,0 +1,39 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2026 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MAIN // + +/** +* Converts an unsigned 64-bit integer to a BigInt. +* +* @private +* @returns {BigInt} BigInt value +*/ +function toBigInt() { + /* eslint-disable no-invalid-this */ + if ( typeof this._raw === 'bigint' ) { + return this._raw; + } +} + + +// EXPORTS // + +module.exports = toBigInt; diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js index fd8df087dcbd..c04d4fbebacf 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tojson.js @@ -1,4 +1,3 @@ -/* eslint-disable no-invalid-this */ /** * @license Apache-2.0 * @@ -26,15 +25,11 @@ * @returns {Object} JSON representation */ function toJSON() { + /* eslint-disable no-invalid-this */ var out = {}; out.type = 'Uint64'; - if ( typeof this.value === 'bigint' ) { - out.value = this.value.toString(); - } - else { - out.value = [ this.value[ 0 ], this.value[ 1 ] ]; - } - // TODO: is it bad to have 2 different kind of json representation? + out.high = this.getHighWord(); + out.low = this.getLowWord(); return out; } diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js index 0b55aeb6cc11..9c2848b16bc1 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/tostring.js @@ -16,17 +16,17 @@ * limitations under the License. */ -/* eslint-disable vars-on-top */ -/* eslint-disable stdlib/vars-order */ -/* eslint-disable no-invalid-this */ - 'use strict'; // MODULES // +var format = require( '@stdlib/string/format' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; var lpad = require( '@stdlib/string/left-pad' ); -// Helper constants for toString base conversion + +// VARIABLES // + var TWO_16 = 0x10000; var TWO_32 = 0x100000000; @@ -173,45 +173,6 @@ var POWERMAP = { } }; - -// MAIN // - -/** -* Serializes an unsigned 64-bit integer as a string in the specified base. -* -* @private -* @param {number} radix - The radix (base) to use for string conversion -* @returns {string} The serialized unsigned 64-bit integer as a string. -* -* **Note** -* This implementation handles 64-bit unsigned integers represented as either a BigInt or a pair of 32-bit words ([high, low]). -* For non-BigInt values, the conversion uses a precomputed POWERMAP to select a divisor and chunk size for efficient base conversion. -* The divisor values are chosen to be close to powers of 2^32 for each supported base, which is an unusual but efficient approach for chunked conversion. -* The function pads the lower chunk with leading zeros to ensure correct digit alignment. -*/ -function toString( radix ) { // eslint-disable-line stdlib/no-redeclare - // eslint-disable-next-line no-undefined - if ( radix === undefined ) { - radix = 10; - } - // TODO: validate base range (between 2 and 36) - if ( typeof this.value === 'bigint' ) { - return this.value.toString( radix ); - } - - var qr = chunkedDivMod( this.value, POWERMAP[ radix ].divisor ); - var sq = qr[ 0 ].toString( radix ); - var sr = qr[ 1 ].toString( radix ); - if ( sq === '0' ) { - sq = ''; - } - else { - sr = lpad( sr, POWERMAP[ radix ].power, '0' ); - } - - return sq + sr; -} - /** * Performs division and modulo for an unsigned 64-bit integer represented as high-low words. * @@ -225,26 +186,28 @@ function toString( radix ) { // eslint-disable-line stdlib/no-redeclare * // returns [ 4, 294967296 ] */ function chunkedDivMod( words, divisor ) { - var hi = words[0] >>> 0; - var lo = words[1] >>> 0; - - var quo = ( hi / divisor ) >>> 0; - var rem = hi - ( divisor * quo ); + var high; + var low; + var quo; + var rem; var qrd; if (divisor === TWO_32) { - return [ hi, lo ]; + return words; } - rem = ( rem * TWO_16 ) + ( lo >>> 16 ); - qrd = ( rem / divisor ) >>> 0; + high = words[0] >>> 0; + low = words[1] >>> 0; + quo = ( high / divisor ) >>> 0; + rem = high - ( divisor * quo ); + rem = ( rem * TWO_16 ) + ( low >>> 16 ); + qrd = ( rem / divisor ) >>> 0; quo = ( quo * TWO_16 ) + qrd; rem -= divisor * qrd; - rem = ( rem * TWO_16 ) + ( lo & 0xffff ); + rem = ( rem * TWO_16 ) + ( low & 0xffff ); qrd = ( rem / divisor ) >>> 0; - quo = ( quo * TWO_16 ) + qrd; rem -= divisor * qrd; @@ -252,6 +215,50 @@ function chunkedDivMod( words, divisor ) { } +// MAIN // + +/** +* Serializes an unsigned 64-bit integer as a string in the specified base. +* +* @param {number} [radix] - The radix (base) to use for string conversion (2-36). Defaults to 10 if not provided. +* @throws {TypeError} Throws an error if radix is not an integer between 2 and 36. +* @returns {string} The serialized unsigned 64-bit integer as a string. +* +*/ +function toString( radix ) { // eslint-disable-line stdlib/no-redeclare + var res; + var quo; + var rem; + + if ( radix === undefined ) { // eslint-disable-line no-undefined + radix = 10; + } + else if ( !isInteger( radix ) || radix < 2 || radix > 36 ) { + throw new TypeError( format( 'invalid argument. Provided radix must be an integer between 2 and 36. Radix: `%s`.', radix ) ); + } + + /* eslint-disable no-invalid-this */ + if ( typeof this._raw === 'bigint' ) { + return this._raw.toString( radix ); + } + + // For non-BigInt mode, the conversion uses a precomputed POWERMAP to select a divisor and chunk size for efficient base conversion. + // The divisor values are chosen to be a power of the radix closest to 2^32 for efficient chunked conversion. + res = chunkedDivMod( this._raw, POWERMAP[ radix ].divisor ); + quo = res[ 0 ].toString( radix ); + rem = res[ 1 ].toString( radix ); + + if ( quo === '0' ) { + quo = ''; + } + else { + rem = lpad( rem, POWERMAP[ radix ].power, '0' ); + } + + return quo + rem; +} + + // EXPORTS // module.exports = toString; diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js b/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js index 7393f15f6a1b..9f7941132b6b 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/lib/valueof.js @@ -1,4 +1,3 @@ -/* eslint-disable no-invalid-this */ /** * @license Apache-2.0 * @@ -23,6 +22,9 @@ var Number = require( '@stdlib/number/ctor' ); + +// VARIABLES // + var TWO_32 = 0x100000000; @@ -35,11 +37,12 @@ var TWO_32 = 0x100000000; * @returns {number} primitive value */ function valueOf() { // eslint-disable-line stdlib/no-redeclare - if ( typeof this.value === 'bigint' ) { - return Number( this.value ); + /* eslint-disable no-invalid-this */ + if ( typeof this._raw === 'bigint' ) { + return Number( this._raw ); } - return ( this.value[ 0 ] * TWO_32 ) + this.value[ 1 ]; + return ( this._raw[ 0 ] * TWO_32 ) + this._raw[ 1 ]; } From 45ecf21de13744c3984e0f266816f8ed72de7e07 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Thu, 19 Mar 2026 11:21:45 +0600 Subject: [PATCH 27/29] test: update and add tests --- .../@stdlib/number/uint64/ctor/README.md | 5 +- .../number/uint64/ctor/examples/index.js | 2 +- .../@stdlib/number/uint64/ctor/test/test.js | 344 ++++++++---------- 3 files changed, 152 insertions(+), 199 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/README.md b/lib/node_modules/@stdlib/number/uint64/ctor/README.md index c671f2193dcb..f98ded1b6e01 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/README.md +++ b/lib/node_modules/@stdlib/number/uint64/ctor/README.md @@ -113,7 +113,8 @@ var o = x.toJSON(); /* { "type": "Uint64", - "value": '5' + "high": 0, + "low": 5 } */ ``` @@ -171,7 +172,7 @@ console.log( 'str: %s', x ); // => 'str: 1234' console.log( 'JSON: %s', JSON.stringify( x ) ); -// => 'JSON: {"type":"Uint64","value":"1234"}' +// => 'JSON: {"type":"Uint64","high":0,"low":1234}' ``` diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js b/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js index f2c9595e4695..c494b474cbc7 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/examples/index.js @@ -29,4 +29,4 @@ console.log( 'str: %s', x ); // => 'str: 5' console.log( 'JSON: %s', JSON.stringify( x ) ); -// => 'JSON: {"type":"Uint64","value":"5"}' +// => 'JSON: {"type":"Uint64","high":0,"low":5}' 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 652003510974..aac20877d244 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/ctor/test/test.js @@ -16,18 +16,20 @@ * limitations under the License. */ +/* eslint-disable no-unused-vars */ + 'use strict'; // MODULES // var tape = require( 'tape' ); var BigInt = require( '@stdlib/bigint/ctor' ); +var UINT32_MAX = require( '@stdlib/constants/uint32/max' ); +var Uint32Array = require( '@stdlib/array/uint32' ); var hasBigIntSupport = require( '@stdlib/assert/has-bigint-support' ); -var hasToPrimSymSupport = require( '@stdlib/assert/has-to-primitive-symbol-support' ); var hasOwnProp = require( '@stdlib/assert/has-own-property' ); -var isUint32Array = require( '@stdlib/assert/is-uint32array' ); -var Uint32Array = require( '@stdlib/array/uint32' ); -var ToPrimitiveSymbol = require( '@stdlib/symbol/to-primitive' ); +var parseUint64dw = require( './../lib/parseuint64dw.js' ); +var toString = require( './../lib/tostring.js' ); // eslint-disable-line stdlib/no-redeclare var Uint64 = require( './../lib' ); @@ -65,7 +67,7 @@ tape( 'the constructor throws an error if not provided a number or string or Arr function badValue( value ) { return function badValue() { - var x = new Uint64( value ); // eslint-disable-line no-unused-vars + var x = new Uint64( value ); }; } }); @@ -113,31 +115,17 @@ tape( 'the constructor prototype has a read-only `BYTES_PER_ELEMENT` property', } }); -// TODO: commented out because value should be private right? -/* -tape( 'the constructor returns an instance having a property for accessing the underlying value', function test( t ) { - var x = new Uint64( 5 ); - t.strictEqual( x.value.toString(), '5', 'returns expected value' ); - t.end(); -}); - -tape( 'the constructor returns an instance which throws an error when attempting to mutate the value', function test( t ) { +tape( 'the constructor stores an internal read-only `_raw` representation', function test( t ) { var x = new Uint64( 5 ); + t.strictEqual( hasOwnProp( x, '_raw' ), true, 'has property' ); t.throws( foo, Error, 'throws an error' ); t.end(); function foo() { - x.value = -5; + x._raw = 1; // eslint-disable-line no-underscore-dangle } }); -tape( 'the constructor returns an instance which stores a provided value as an unsigned 64-bit integer', function test( t ) { - var x = new Uint64( 3 ); - t.strictEqual( x.value.toString(), '3', 'returns expected value' ); - t.end(); -}); -*/ - tape( 'if provided a BigInt, the constructor stores the lower 64 bits', function test( t ) { var x; @@ -146,173 +134,108 @@ tape( 'if provided a BigInt, the constructor stores the lower 64 bits', function t.end(); return; } + x = new Uint64( BigInt( '18446744073709551616' ) ); t.strictEqual( x.toString(), '0', 'returns expected value' ); - t.end(); -}); -tape( 'if provided a BigInt and a high-low flag, the constructor stores a Uint32Array', function test( t ) { - var x; + x = new Uint64( BigInt( '18446744073709551615' ) ); + t.strictEqual( x.toString(), '18446744073709551615', 'returns expected value' ); - if ( !hasBigIntSupport() ) { - t.pass( 'environment does not support BigInt' ); - t.end(); - return; - } - x = new Uint64( BigInt( '18446744073709551616' ), true ); - t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 0, 0 ], 'returns expected value' ); + x = new Uint64( BigInt( '5' ) ); + t.strictEqual( x.toString(), '5', 'returns expected value' ); t.end(); }); -tape( 'if provided a Uint32Array of length 2 and no high-low flag, the constructor stores the expected numeric value', function test( t ) { - var x; - - x = new Uint64( new Uint32Array( [ 1, 2 ] ) ); +tape( 'if provided a Uint32Array of length 2, the constructor stores the expected numeric value', function test( t ) { + var x = new Uint64( new Uint32Array( [ 1, 2 ] ) ); t.strictEqual( x.toString(), '4294967298', 'returns expected value' ); t.end(); }); -tape( 'if provided a Uint32Array of length 2 and a high-low flag, the constructor stores a Uint32Array value', function test( t ) { - var x; - - x = new Uint64( new Uint32Array( [ 1, 2 ] ), true ); - t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 2 ], 'returns expected value' ); - t.end(); -}); - tape( 'if provided a Uint32Array which does not have length 2, the constructor throws an error', function test( t ) { t.throws( badValue, TypeError, 'throws an error' ); t.end(); function badValue() { - var x = new Uint64( new Uint32Array( 1 ) ); // eslint-disable-line no-unused-vars + var x = new Uint64( new Uint32Array( 1 ) ); } }); -tape( 'if provided an array of length 2 and no high-low flag, the constructor stores the expected numeric value', function test( t ) { - var x; - - x = new Uint64( [ 1, 2 ] ); +tape( 'if provided an array of two valid words, the constructor stores the expected numeric value', function test( t ) { + var x = new Uint64( [ 1, 2 ] ); t.strictEqual( x.toString(), '4294967298', 'returns expected value' ); t.end(); }); -tape( 'if provided an array of length 2 and a high-low flag, the constructor stores a Uint32Array value', function test( t ) { - var x; - - x = new Uint64( [ 1, 2 ], true ); - t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 2 ], 'returns expected value' ); - t.end(); -}); - -tape( 'if provided an array of length 2 with float values, the constructor coerces words to uint32', function test( t ) { - var x; - - x = new Uint64( [ 1.9, 2.1 ], true ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 2 ], 'returns expected value' ); - t.end(); -}); - -tape( 'if provided an array with a length not equal to 2, the constructor throws an error', function test( t ) { - t.throws( badValue, TypeError, 'throws an error' ); - t.end(); +tape( 'if provided an invalid word array, the constructor throws an error', function test( t ) { + var values; + var i; - function badValue() { - var x = new Uint64( [ 1 ] ); // eslint-disable-line no-unused-vars + values = [ + [ 1 ], + [ 1.9, 2 ], + [ '1', 2 ], + [ -1, 2 ], + [ UINT32_MAX + 1, 0 ] + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); } -}); - -tape( 'if provided an array containing non-number elements, the constructor throws an error', function test( t ) { - t.throws( badValue, TypeError, 'throws an error' ); t.end(); - function badValue() { - var x = new Uint64( [ '1', 2 ] ); // eslint-disable-line no-unused-vars + function badValue( value ) { + return function badValue() { + var x = new Uint64( value ); + }; } }); -tape( 'if provided an array containing out-of-range numbers, the constructor throws an error', function test( t ) { - t.throws( badValue, TypeError, 'throws an error' ); - t.end(); +tape( 'if provided a valid unsigned integer string, the constructor stores the lower 64 bits', function test( t ) { + var x; - function badValue() { - var x = new Uint64( [ -1, 2 ] ); // eslint-disable-line no-unused-vars - } -}); + x = new Uint64( '18446744073709551616' ); + t.strictEqual( x.toString(), '0', 'returns expected value' ); -tape( 'if provided a valid integer-valued string and no high-low flag, the constructor stores the expected numeric value', function test( t ) { - var x; + x = new Uint64( '18446744073709551615' ); + t.strictEqual( x.toString(), '18446744073709551615', 'returns expected value' ); - x = new Uint64( '123456' ); - t.strictEqual( x.toString(), '123456', 'returns expected value' ); - t.end(); -}); + x = new Uint64( '5' ); + t.strictEqual( x.toString(), '5', 'returns expected value' ); -tape( 'if provided an invalid string and no high-low flag, the constructor throws an error', function test( t ) { - t.throws( badValue, TypeError, 'throws an error' ); + // TODO: Should empty string be supported? + x = new Uint64( '' ); + t.strictEqual( x.toString(), '0', 'returns expected value' ); t.end(); - - function badValue() { - var x = new Uint64( 'beep boop' ); // eslint-disable-line no-unused-vars - } }); -tape( 'if provided a string and a high-low flag, the constructor stores the same numeric value as in BigInt mode', function test( t ) { - var x; - - x = new Uint64( '123456', true ); - t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 0, 123456 ], 'returns expected value' ); - t.strictEqual( x.toString(), '123456', 'returns expected value' ); - - x = new Uint64( '4294967296', true ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 0 ], 'returns expected value' ); - t.strictEqual( x.toString(), '4294967296', 'returns expected value' ); +tape( 'if provided an invalid unsigned integer string, the constructor throws an error', function test( t ) { + var values; + var i; - t.throws( badValue, TypeError, 'throws an error for invalid string' ); + values = [ + 'beep boop', + '-5', + '0x', + '0b2', + '4a5' + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } t.end(); - function badValue() { - var x = new Uint64( 'beep boop', true ); // eslint-disable-line no-unused-vars + function badValue( value ) { + return function badValue() { + var x = new Uint64( value ); + }; } }); -tape( 'if provided prefixed or whitespace-padded strings and a high-low flag, the constructor parses the expected numeric value', function test( t ) { - // TODO: generated tests, to be refined - var x; - - x = new Uint64( ' 123456 ', true ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 0, 123456 ], 'parses whitespace-padded decimal string' ); - t.strictEqual( x.toString(), '123456', 'returns expected decimal string' ); - - x = new Uint64( '1234567890123', true ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 287, 1912276171 ], 'parses chunked decimal string' ); - t.strictEqual( x.toString(), '1234567890123', 'preserves decimal numeric value' ); - - x = new Uint64( '0x123456789abcdef0', true ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 0x12345678, 0x9abcdef0 ], 'parses hexadecimal string' ); - t.strictEqual( x.toString( 16 ), '123456789abcdef0', 'returns expected hexadecimal string' ); - - x = new Uint64( '0o10000000000000000', true ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 0 ], 'parses octal string' ); - t.strictEqual( x.toString(), '4294967296', 'returns expected decimal value for octal input' ); - - x = new Uint64( '0b100000000000000000000000000000000', true ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 0 ], 'parses binary string' ); - t.strictEqual( x.toString(), '4294967296', 'returns expected decimal value for binary input' ); - - t.end(); -}); - -tape( 'if provided a valid number and a high-low flag, the constructor stores high-low words', function test( t ) { +tape( 'if provided a valid number, the constructor stores the expected numeric value', function test( t ) { var x; - x = new Uint64( 4294967301, true ); - t.strictEqual( isUint32Array( x.value ), true, 'returns expected value' ); - t.deepEqual( [ x.value[ 0 ], x.value[ 1 ] ], [ 1, 5 ], 'returns expected value' ); + x = new Uint64( 4294967301 ); + t.strictEqual( x.toString(), '4294967301', 'returns expected value' ); t.end(); }); @@ -332,30 +255,44 @@ tape( 'if provided an invalid number, the constructor throws an error', function function badValue( value ) { return function badValue() { - var x = new Uint64( value ); // eslint-disable-line no-unused-vars + var x = new Uint64( value ); }; } }); -tape( 'the constructor returns an instance which supports serializing an instance as a string', function test( t ) { +tape( 'instances support serializing to string for supported radices', function test( t ) { var x; x = new Uint64( 5 ); t.strictEqual( x.toString(), '5', 'returns expected value' ); + t.strictEqual( x.toString( 16 ), '5', 'returns expected value' ); - x = new Uint64( [ 1, 0 ], true ); + x = new Uint64( [ 1, 0 ] ); t.strictEqual( x.toString( 16 ), '100000000', 'returns expected value' ); + t.end(); +}); - x = new Uint64( [ 0, 15 ], true ); - t.strictEqual( x.toString( 16 ), 'f', 'returns expected value' ); - - x = new Uint64( [ 0, 5 ], true ); - t.strictEqual( x.toString( 10 ), '5', 'returns expected value' ); - - x = new Uint64( 255 ); - t.strictEqual( x.toString(16), 'ff', 'returns expected value' ); +tape( 'instances throw when provided an invalid radix', function test( t ) { + var values; + var i; + var x = new Uint64( 5 ); + values = [ + 1, + -1, + 2.5, + 37 + ]; + for ( i = 0; i < values.length; i++ ) { + t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + } t.end(); + + function badValue( value ) { + return function badValue() { + var y = x.toString( value ); + }; + } }); tape( 'the constructor returns an instance which supports serializing an instance as a JSON object', function test( t ) { @@ -365,32 +302,30 @@ tape( 'the constructor returns an instance which supports serializing an instanc x = new Uint64( 5 ); expected = { 'type': 'Uint64', - 'value': '5' + 'high': 0, + 'low': 5 }; t.deepEqual( x.toJSON(), expected, 'returns expected value' ); t.strictEqual( JSON.stringify( x ), JSON.stringify( expected ), 'returns expected value' ); - // TODO: test array format of toJSON if applicable after review - x = new Uint64( [ 1, 2 ], true ); + x = new Uint64( [ 1, 2 ] ); expected = { 'type': 'Uint64', - 'value': [ 1, 2 ] + 'high': 1, + 'low': 2 }; t.deepEqual( x.toJSON(), expected, 'returns expected value' ); t.end(); }); -tape( 'the constructor returns an instance which supports converting an instance to a primitive value', function test( t ) { +tape( 'instances support converting to a primitive number', function test( t ) { var x; x = new Uint64( 5 ); t.strictEqual( x.valueOf(), 5, 'returns expected value' ); - x = new Uint64( [ 0xffffffff, 0xffffffff ] ); - t.strictEqual( x.valueOf(), 18446744073709552000, 'returns expected value' ); - - x = new Uint64( [ 0xffffffff, 0xffffffff ], true ); + x = new Uint64( [ UINT32_MAX, UINT32_MAX ] ); t.strictEqual( x.valueOf(), 18446744073709552000, 'returns expected value' ); x = new Uint64( Number.MAX_SAFE_INTEGER ); @@ -399,54 +334,71 @@ tape( 'the constructor returns an instance which supports converting an instance t.end(); }); -tape( 'if an environment supports `Symbol.toPrimitive`, instances expose a toPrimitive method', function test( t ) { +tape( 'instances expose high and low word accessors', function test( t ) { var x; - if ( !hasToPrimSymSupport() ) { - t.pass( 'environment does not support Symbol.toPrimitive' ); + x = new Uint64( [ 1, 2 ] ); + t.strictEqual( x.getHighWord(), 1, 'returns expected value' ); + t.strictEqual( x.getLowWord(), 2, 'returns expected value' ); + t.end(); +}); + +tape( 'if BigInt is supported, instances provide `toBigInt()`', function test( t ) { + var x; + + if ( !hasBigIntSupport() ) { + t.strictEqual( hasOwnProp( Uint64.prototype, 'toBigInt' ), false, 'prototype does not provide `toBigInt`' ); t.end(); return; } - x = new Uint64( 5 ); - t.strictEqual( x[ ToPrimitiveSymbol ]( 'number' ), 5, 'returns expected value' ); + t.strictEqual( hasOwnProp( Uint64.prototype, 'toBigInt' ), true, 'prototype provides `toBigInt`' ); + + x = new Uint64( [ 1, 2 ] ); + t.strictEqual( x.toBigInt().toString(), '4294967298', 'returns expected value' ); t.end(); }); -// TODO: we discussed that direct operations will not be supported without the functional utils -// And should we actually remove the ToPrimitive function? -/* -tape( 'the constructor returns an instance which supports implicit type coercion', function test( t ) { - var x; - var y; +tape( '`parseUint64dw()` parses prefixed, whitespace-padded, decimal, and invalid strings', function test( t ) { + var out; + + out = parseUint64dw( '0xffffffff0000ffff' ); + t.deepEqual( out, [ 4294967295, 65535 ], 'parses hex word pair' ); + + out = parseUint64dw( '0x1ffffffff0000ffff' ); + t.deepEqual( out, [ 4294967295, 65535 ], 'truncates over-wide hex to 64 bits' ); - x = new Uint64( 10.0 ); - t.strictEqual( x + 5, 15.0, 'returns expected value' ); - t.strictEqual( x * 2, 20.0, 'returns expected value' ); + out = parseUint64dw( '0xffff' ); + t.deepEqual( out, [ 0, 65535 ], 'parses short hex string' ); - x = new Uint64( 3.0 ); - y = new Uint64( 2.0 ); - t.strictEqual( x + y, 5, 'returns expected value' ); + out = parseUint64dw( '0o100' ); + t.deepEqual( out, [ 0, 64 ], 'parses octal string' ); + out = parseUint64dw( '0b100' ); + t.deepEqual( out, [ 0, 4 ], 'parses binary string' ); + + out = parseUint64dw( '4294967296' ); + t.deepEqual( out, [ 1, 0 ], 'parses decimal into high/low words' ); + + out = parseUint64dw( ' 123456 ' ); + t.deepEqual( out, [ 0, 123456 ], 'parses whitespace-padded decimal string' ); + + out = parseUint64dw( 'beep boop' ); + t.ok( isNaN( out[ 0 ] ) && isNaN( out[ 1 ] ), 'returns NaN words for invalid input' ); t.end(); }); -tape( 'if an environment supports `Symbol.toPrimitive`, the constructor returns an instance which supports type coercion', function test( t ) { +tape( '`toString()` helper supports Uint32Array backed objects', function test( t ) { var x; - if ( !hasToPrimitiveSymbolSupport() ) { - t.ok( true, 'environment does not support Symbol.toPrimitive' ); - t.end(); - return; - } - x = new Uint64( 5 ); - - t.strictEqual( x[ ToPrimitiveSymbol ]( 'number' ), 5, 'returns expected value' ); - t.strictEqual( x[ ToPrimitiveSymbol ]( 'default' ), 5, 'returns expected value' ); - t.strictEqual( x[ ToPrimitiveSymbol ]( 'string' ), 5, 'returns expected value' ); - - x = new Uint64( -3.14 ); - t.strictEqual( x[ ToPrimitiveSymbol ](), -3.140625, 'returns expected value' ); + x = { + '_raw': new Uint32Array( [ 1, 0 ] ) + }; + t.strictEqual( toString.call( x, 16 ), '100000000', 'returns expected hexadecimal string' ); + t.strictEqual( toString.call( x, 10 ), '4294967296', 'returns expected decimal string' ); + x = { + '_raw': new Uint32Array( [ 0, 100 ] ) + }; + t.strictEqual( toString.call( x, 3 ), '10201', 'returns expected string' ); t.end(); }); -*/ From 071df31c6d372225352dc25170512646b70368c5 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Thu, 19 Mar 2026 11:35:10 +0600 Subject: [PATCH 28/29] docs: update type declaration --- .../number/uint64/ctor/docs/types/index.d.ts | 57 +++++++++++++++---- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts index 06f0e5be03c4..8f973ed2a539 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts @@ -25,7 +25,7 @@ declare class Uint64 { /** * Unsigned 64-bit integer constructor. * - * @param value - numeric value + * @param value - numeric value or string or word array or BigInt * @returns unsigned 64-bit integer * * @example @@ -35,13 +35,6 @@ declare class Uint64 { constructor( value: number | string | Array | Uint32Array | BigInt ); // TODO: do we need to import Uint32Array and BigInt here in this file as well? - /** - * Read-only property returning the value. - * - * @returns value - */ - // readonly value: number; - // TODO: disabled because should be private, will remove/update after review /** * Size (in bytes) of the underlying value. @@ -57,6 +50,7 @@ declare class Uint64 { /** * Serializes an unsigned 64-bit integer as a string. * + * @param radix - output radix/base (integer from 2 to 36) * @returns serialized unsigned 64-bit integer * * @example @@ -65,7 +59,7 @@ declare class Uint64 { * var str = x.toString(); * // returns '5' */ - toString(): string; + toString( radix?: number ): string; /** * Serializes an unsigned 64-bit integer as a JSON object. @@ -81,7 +75,7 @@ declare class Uint64 { * var x = new Uint64( 5 ); * * var obj = x.toJSON(); - * // returns { 'type': 'Uint64', 'value': '5' } + * // returns { 'type': 'Uint64', 'high': 0, 'low': 5 } */ toJSON(): any; @@ -97,6 +91,49 @@ declare class Uint64 { * // returns 5.0 */ valueOf(): number; + + /** + * Returns the high 32-bit word of an unsigned 64-bit integer. + * + * @returns high 32-bit word + * + * @example + * var x = new Uint64( [ 1, 2 ] ); + * + * var w = x.getHighWord(); + * // returns 1 + */ + getHighWord(): number; + + /** + * Returns the low 32-bit word of an unsigned 64-bit integer. + * + * @returns low 32-bit word + * + * @example + * var x = new Uint64( [ 1, 2 ] ); + * + * var w = x.getLowWord(); + * // returns 2 + */ + getLowWord(): number; + + /** + * Converts an unsigned 64-bit integer to a BigInt. + * + * ## Notes + * + * - This method is only available in environments supporting BigInt. + * + * @returns BigInt value + * + * @example + * var x = new Uint64( [ 1, 2 ] ); + * + * var v = x.toBigInt(); + * // returns 4294967298n + */ + toBigInt?(): bigint; } From 0ee526d3b620516d95d4d6a5beef94e40969f5fb Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Thu, 19 Mar 2026 11:43:09 +0600 Subject: [PATCH 29/29] docs: fix type declaration --- .../@stdlib/number/uint64/ctor/docs/types/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts index 8f973ed2a539..ade92f613987 100644 --- a/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/number/uint64/ctor/docs/types/index.d.ts @@ -130,8 +130,8 @@ declare class Uint64 { * @example * var x = new Uint64( [ 1, 2 ] ); * - * var v = x.toBigInt(); - * // returns 4294967298n + * var v = x.toBigInt().toString(); + * // returns '4294967298' */ toBigInt?(): bigint; }