From dd5f89f0e62a99ccd4b2e539251afd874297f2cc Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 22 May 2026 03:46:33 +0600 Subject: [PATCH 01/11] feat: implement `fromString` function to parse strings as unsigned 64-bit integers --- 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: passed - 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/from-string/lib/index.js | 40 ++++++ .../number/uint64/from-string/lib/main.js | 65 +++++++++ .../number/uint64/from-string/lib/parse.js | 123 ++++++++++++++++++ .../number/uint64/from-string/package.json | 63 +++++++++ 4 files changed, 291 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/lib/index.js create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/package.json diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/index.js b/lib/node_modules/@stdlib/number/uint64/from-string/lib/index.js new file mode 100644 index 000000000000..cccd1ebe25fe --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/lib/index.js @@ -0,0 +1,40 @@ +/** +* @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'; + +/** +* Parse a string as an unsigned 64-bit integer. +* +* @module @stdlib/number/uint64/from-string +* +* @example +* var fromString = require( '@stdlib/number/uint64/from-string' ); +* +* var v = fromString( '5' ); +* // returns +*/ + +// MAIN // + +var main = require( './main.js' ); + + +// EXPORTS // + +module.exports = main; diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js b/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js new file mode 100644 index 000000000000..e2c4bc88c032 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js @@ -0,0 +1,65 @@ +/** +* @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 isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var Uint64 = require( '@stdlib/number/uint64/ctor' ); +var trim = require( '@stdlib/string/base/trim' ); +var format = require( '@stdlib/string/format' ); +var parse = require( './parse.js' ); + + +// MAIN // + +/** +* Parses a string as an unsigned 64-bit integer. +* +* @param {string} str - input string +* @throws {TypeError} must provide a string encoding a nonnegative integer +* @returns {Uint64} unsigned 64-bit integer +* +* @example +* var v = fromString( '5' ); +* // returns +*/ +function fromString( str ) { + var v; + if ( !isString( str ) ) { + throw new TypeError( format( 'invalid argument. Must provide a string. Value: `%s`.', str ) ); + } + v = trim( str ); + if ( v[ 0 ] === '-' ) { + throw new TypeError( format( 'invalid argument. Must provide a string encoding a nonnegative integer. Value: `%s`.', str ) ); + } + if ( v[ 0 ] === '+' ) { + v = v.slice( 1 ); + } + v = parse( v ); + if ( v[ 0 ] === -1 ) { + throw new TypeError( format( 'invalid argument. Must provide a string encoding a nonnegative integer. Value: `%s`.', str ) ); + } + return Uint64.from( v ); +} + + +// EXPORTS // + +module.exports = fromString; diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js b/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js new file mode 100644 index 000000000000..56d153f55c43 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js @@ -0,0 +1,123 @@ +/** +* @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 max = require( '@stdlib/math/base/special/fast/max' ); +var Number = require( '@stdlib/number/ctor' ); + + +// VARIABLES // + +var TWO_32 = 0x100000000; // 2^32 +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 a double word representation of unsigned 64 bit integer. +* +* @private +* @param {string} value - string representation of an unsigned integer +* @returns {Array} high and low words of an unsigned 64-bit integer +* +* @example +* var v = parseString( '0xffffffff0000ffff' ); +* // returns [ 4294967295, 65535 ] +* +* v = parseString( '0x1ffffffff0000ffff' ); +* // returns [ 4294967295, 65535 ] +* +* v = parseString( '0xffff' ); +* // returns [ 0, 65535 ] +* +* v = parseString( '0o100' ); +* // returns [ 0, 64 ] +* +* v = parseString( '0b100' ); +* // returns [ 0, 4 ] +* +* v = parseString( '4294967296' ); +* // returns [ 1, 0 ] +*/ +function parseString( value ) { + var high; + var low; + var tmp; + var j; + var i; + + if ( RE_HEX.test( value ) ) { + j = max( 2, value.length - 8 ); + i = max( 2, value.length - 16 ); + return [ + Number( '0x0' + value.slice( i, j ) ), + Number( '0x' + value.slice( j ) ) + ]; + } + if ( RE_OCT.test( value ) ) { + j = max( 2, value.length - 16 ); + i = max( 2, value.length - 32 ); + return [ + Number( '0o0' + value.slice( i, j ) ), + Number( '0o' + value.slice( j ) ) + ]; + } + if ( RE_BIN.test( value ) ) { + j = max( 2, value.length - 32 ); + i = max( 2, value.length - 64 ); + return [ + Number( '0b0' + value.slice( i, j ) ), + Number( '0b' + value.slice( j ) ) + ]; + } + if ( RE_INV.test( value ) ) { + return [ -1, -1 ]; + } + // Chunked parsing for decimal string... + + // Process the first chunk so that the remaining chunks are all evenly sized (6 digits): + i = ( value.length % 6 ) || 6; + if ( i + 6 <= 9 ) { + // If possible, take a bigger chunk: + 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 = parseString; diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/package.json b/lib/node_modules/@stdlib/number/uint64/from-string/package.json new file mode 100644 index 000000000000..8e16d143e9f8 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/package.json @@ -0,0 +1,63 @@ +{ + "name": "@stdlib/number/uint64/from-string", + "version": "0.0.0", + "description": "Parse a string as an 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", + "lib": "./lib", + "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", + "uint64", + "unsigned", + "64-bit", + "integer", + "int" + ] +} From 7a258ba0faddc1759dd7338d87e45ec40be712ff Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 23 May 2026 21:59:14 +0600 Subject: [PATCH 02/11] docs: add readme and example --- .../number/uint64/from-string/README.md | 128 ++++++++++++++++++ .../uint64/from-string/examples/index.js | 32 +++++ 2 files changed, 160 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/README.md create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/README.md b/lib/node_modules/@stdlib/number/uint64/from-string/README.md new file mode 100644 index 000000000000..73f2db20e295 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/README.md @@ -0,0 +1,128 @@ + + +# fromString + +> Parse a string as an unsigned 64-bit integer. + + + +
+ +
+ + + + + +
+ +## Usage + +```javascript +var fromString = require( '@stdlib/number/uint64/from-string' ); +``` + +#### fromString( str ) + +Parses a string as an unsigned 64-bit integer. + +```javascript +var str = '1234'; +var x = fromString( str ); +// returns + +str = '0x1234567890abcdef' +x = fromString( str ); +// returns +``` + +* * * + + + +
+ +## Notes + +- An unsigned 64-bit integer has a range of \[`0`, `2^64-1`\]. +- If the provided string represents a value greater than `2^64-1` it is truncated to 64 least significant bits. + +
+ + + +* * * + + + +
+ +## Examples + + + +```javascript +var fromString = require( '@stdlib/number/uint64/from-string' ); + +var x = fromString( '1234' ); + +console.log( 'type: %s', typeof x ); +// => 'type: object' + +console.log( 'str: %s', x ); +// => 'str: 1234' + +console.log( 'JSON: %s', JSON.stringify( x ) ); +// => 'JSON: {"type":"Uint64","words":[0,1234]}' +``` + +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js b/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js new file mode 100644 index 000000000000..83435a107812 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js @@ -0,0 +1,32 @@ +/** +* @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'; + +var fromString = require( '@stdlib/number/uint64/from-string' ); + +var x = fromString( '1234' ); + +console.log( 'type: %s', typeof x ); +// => 'type: object' + +console.log( 'str: %s', x ); +// => 'str: 1234' + +console.log( 'JSON: %s', JSON.stringify( x ) ); +// => 'JSON: {"type":"Uint64","words":[0,1234]}' From 38e71698573c966c1782674bc29ee926f45432f1 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Wed, 27 May 2026 22:00:48 +0600 Subject: [PATCH 03/11] bench: add benchmark for `uint64/from-string` --- .../uint64/from-string/benchmark/benchmark.js | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/benchmark/benchmark.js diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/benchmark/benchmark.js b/lib/node_modules/@stdlib/number/uint64/from-string/benchmark/benchmark.js new file mode 100644 index 000000000000..c1301b762f2d --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/benchmark/benchmark.js @@ -0,0 +1,140 @@ +/** +* @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 bench = require( '@stdlib/bench' ); +var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); +var format = require( '@stdlib/string/format' ); +var MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' ); +var Uint64 = require( '@stdlib/number/uint64/ctor' ); +var pkg = require( './../package.json' ).name; +var fromString = require( './../lib' ); + + +// MAIN // + +bench( pkg, function benchmark( b ) { + var x; + var y; + var z; + var i; + + x = discreteUniform( 100, 0, MAX_SAFE_INTEGER ); + y = []; + for ( i = 0; i < x.length; i++ ) { + y.push( x[i].toString() ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + z = fromString( y[ i % y.length ] ); + if ( typeof z !== 'object' ) { + b.fail( 'should return a Uint64 instance' ); + } + } + b.toc(); + if ( !( z instanceof Uint64 ) ) { + b.fail( 'should return a Uint64 instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( format( '%s:hexadecimal', pkg ), function benchmark( b ) { + var x; + var y; + var z; + var i; + + x = discreteUniform( 100, 0, MAX_SAFE_INTEGER ); + y = []; + for ( i = 0; i < x.length; i++ ) { + y.push( '0x'+x[i].toString( 16 ) ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + z = fromString( y[ i % y.length ] ); + if ( typeof z !== 'object' ) { + b.fail( 'should return a Uint64 instance' ); + } + } + b.toc(); + if ( !( z instanceof Uint64 ) ) { + b.fail( 'should return a Uint64 instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( format( '%s:binary', pkg ), function benchmark( b ) { + var x; + var y; + var z; + var i; + + x = discreteUniform( 100, 0, MAX_SAFE_INTEGER ); + y = []; + for ( i = 0; i < x.length; i++ ) { + y.push( '0b'+x[i].toString( 2 ) ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + z = fromString( y[ i % y.length ] ); + if ( typeof z !== 'object' ) { + b.fail( 'should return a Uint64 instance' ); + } + } + b.toc(); + if ( !( z instanceof Uint64 ) ) { + b.fail( 'should return a Uint64 instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); + +bench( format( '%s:octal', pkg ), function benchmark( b ) { + var x; + var y; + var z; + var i; + + x = discreteUniform( 100, 0, MAX_SAFE_INTEGER ); + y = []; + for ( i = 0; i < x.length; i++ ) { + y.push( '0o'+x[i].toString( 8 ) ); + } + + b.tic(); + for ( i = 0; i < b.iterations; i++ ) { + z = fromString( y[ i % y.length ] ); + if ( typeof z !== 'object' ) { + b.fail( 'should return a Uint64 instance' ); + } + } + b.toc(); + if ( !( z instanceof Uint64 ) ) { + b.fail( 'should return a Uint64 instance' ); + } + b.pass( 'benchmark finished' ); + b.end(); +}); From 0929c41831694b32fe622a8cef778fbddeb5dca3 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Wed, 27 May 2026 22:01:46 +0600 Subject: [PATCH 04/11] fix: fix octal parsing --- .../number/uint64/from-string/lib/parse.js | 84 ++++++++++--------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js b/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js index 56d153f55c43..d40c6042583a 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js +++ b/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js @@ -27,11 +27,10 @@ var Number = require( '@stdlib/number/ctor' ); // VARIABLES // var TWO_32 = 0x100000000; // 2^32 -var RE_HEX = /^0x/i; -var RE_OCT = /^0o/i; -var RE_BIN = /^0b/i; -var RE_INV = /[^0-9]/; // invalid decimal integer - +var RE_DEC = /^[0-9]+$/; +var RE_HEX = /^0[Xx][0-9A-Fa-f]+$/; +var RE_BIN = /^0[Bb][01]+$/; +var RE_OCT = /^0[Oo][0-7]+$/; // MAIN // @@ -68,53 +67,62 @@ function parseString( value ) { var j; var i; + if ( RE_DEC.test( value ) ) { + // Chunked parsing for decimal string... + // Process the first chunk so that the remaining chunks are all evenly sized (6 digits): + // Because 6 is the maximum number of digits for a decimal integer that can be safely + // multiplied with a 32-bit integer without precision loss. + i = ( value.length % 6 ) || 6; + // If possible, take a bigger chunk: + if ( i + 6 <= 9 ) { + 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 >>> 0, low >>> 0 ]; + } + if ( RE_HEX.test( value ) ) { j = max( 2, value.length - 8 ); i = max( 2, value.length - 16 ); return [ - Number( '0x0' + value.slice( i, j ) ), - Number( '0x' + value.slice( j ) ) - ]; - } - if ( RE_OCT.test( value ) ) { - j = max( 2, value.length - 16 ); - i = max( 2, value.length - 32 ); - return [ - Number( '0o0' + value.slice( i, j ) ), - Number( '0o' + value.slice( j ) ) + Number( '0x0' + value.slice( i, j ) ) >>> 0, + Number( '0x' + value.slice( j ) ) >>> 0 ]; } + if ( RE_BIN.test( value ) ) { j = max( 2, value.length - 32 ); i = max( 2, value.length - 64 ); return [ - Number( '0b0' + value.slice( i, j ) ), - Number( '0b' + value.slice( j ) ) + Number( '0b0' + value.slice( i, j ) ) >>> 0, + Number( '0b' + value.slice( j ) ) >>> 0 ]; } - if ( RE_INV.test( value ) ) { - return [ -1, -1 ]; - } - // Chunked parsing for decimal string... - // Process the first chunk so that the remaining chunks are all evenly sized (6 digits): - i = ( value.length % 6 ) || 6; - if ( i + 6 <= 9 ) { - // If possible, take a bigger chunk: - 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 ( RE_OCT.test( value ) ) { + j = max( 2, value.length - 11 ); + i = max( 2, value.length - 22 ); + + high = Number( '0o0' + value.slice( i, j ) ); + low = Number( '0o' + value.slice( j ) ); + + // Since 11 octal digits are equivalent to 33 bits, 1 msb from `low` will be transferred to `high`. + // And the excess bits in `high` and `low` will be truncated via the `>>> 0`. + high = ( high << 1 ) | ( low >= TWO_32 ); + return [ high >>> 0, low >>> 0 ]; } - return [ high, low ]; + + return [ -1, -1 ]; } From f64486764cae26ee67eb30c9165c976a42a93896 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Wed, 27 May 2026 22:27:51 +0600 Subject: [PATCH 05/11] docs: add repl documentation for `fromString` --- .../number/uint64/from-string/docs/repl.txt | 25 +++++++++++++++++++ .../number/uint64/from-string/lib/main.js | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/docs/repl.txt diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/docs/repl.txt b/lib/node_modules/@stdlib/number/uint64/from-string/docs/repl.txt new file mode 100644 index 000000000000..13dd7c2ee3bf --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/docs/repl.txt @@ -0,0 +1,25 @@ + +{{alias}}( str ) + Parses a string as an unsigned 64-bit integer. + + Parameters + ---------- + str: string + String representation of a nonnegative integer. + + Returns + ------- + v: Uint64 + Unsigned 64-bit integer. + + Examples + -------- + > var x = {{alias}}( '1234' ) + + > x.toString() + '1234' + + + See Also + -------- + diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js b/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js index e2c4bc88c032..7bc55bba267a 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js @@ -32,7 +32,7 @@ var parse = require( './parse.js' ); /** * Parses a string as an unsigned 64-bit integer. * -* @param {string} str - input string +* @param {string} str - string representation of a nonnegative integer * @throws {TypeError} must provide a string encoding a nonnegative integer * @returns {Uint64} unsigned 64-bit integer * From cb883db1ff753d3650b7d5be183d18365c218b0a Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Thu, 28 May 2026 09:19:24 +0600 Subject: [PATCH 06/11] feat: add typescript declarations --- 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_pkg_readmes status: na - task: lint_markdown_docs status: na - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - 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: passed - task: lint_license_headers status: passed --- --- .../uint64/from-string/docs/types/index.d.ts | 40 ++++++++++++++++ .../uint64/from-string/docs/types/test.ts | 48 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/docs/types/index.d.ts create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/docs/types/test.ts diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/index.d.ts new file mode 100644 index 000000000000..3a53ce7c6a04 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/index.d.ts @@ -0,0 +1,40 @@ +/* +* @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. +*/ + +// TypeScript Version: 4.1 + +import Uint64 = require( '@stdlib/number/uint64/ctor' ); + + +/** +* Parses a string as an unsigned 64-bit integer. +* +* @param str - string representation of a nonnegative integer +* @throws must provide a string encoding a nonnegative integer +* @returns unsigned 64-bit integer +* +* @example +* var v = fromString( '5' ); +* // returns +*/ +declare function fromString( str: string ): Uint64; + + +// EXPORTS // + +export = fromString; diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/test.ts b/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/test.ts new file mode 100644 index 000000000000..2035a00b0cd8 --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/test.ts @@ -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. +*/ + +/* eslint-disable @typescript-eslint/no-unused-expressions */ + +import fromString = require( './index' ); + + +// TESTS // + +// The function returns an unsigned 64-bit integer... +{ + fromString( '1234' ); // $ExpectType Uint64 + fromString( '0xabcd' ); // $ExpectType Uint64 + fromString( '0b1010' ); // $ExpectType Uint64 + fromString( '0o1234' ); // $ExpectType Uint64 +} + +// The compiler throws an error if the function is provided an argument which is not a string... +{ + fromString( true ); // $ExpectError + fromString( false ); // $ExpectError + fromString( null ); // $ExpectError + fromString( 123 ); // $ExpectError + fromString( {} ); // $ExpectError + fromString( ( x: number ): number => x ); // $ExpectError +} + +// The compiler throws an error if the function is provided an unsupported number of arguments... +{ + fromString(); // $ExpectError + fromString( '5', '3' ); // $ExpectError +} From d352e3c59d4651f2479861d9889fb0d22d386513 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Thu, 28 May 2026 13:08:22 +0600 Subject: [PATCH 07/11] test: add unit tests for `from-string` --- 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_pkg_readmes status: na - task: lint_markdown_docs status: na - 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: 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/from-string/lib/main.js | 3 +- .../number/uint64/from-string/test/test.js | 335 ++++++++++++++++++ 2 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 lib/node_modules/@stdlib/number/uint64/from-string/test/test.js diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js b/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js index 7bc55bba267a..df048a268f0b 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js @@ -23,6 +23,7 @@ var isString = require( '@stdlib/assert/is-string' ).isPrimitive; var Uint64 = require( '@stdlib/number/uint64/ctor' ); var trim = require( '@stdlib/string/base/trim' ); +var slice = require( '@stdlib/string/base/slice' ); var format = require( '@stdlib/string/format' ); var parse = require( './parse.js' ); @@ -50,7 +51,7 @@ function fromString( str ) { throw new TypeError( format( 'invalid argument. Must provide a string encoding a nonnegative integer. Value: `%s`.', str ) ); } if ( v[ 0 ] === '+' ) { - v = v.slice( 1 ); + v = slice( v, 1 ); } v = parse( v ); if ( v[ 0 ] === -1 ) { diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js b/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js new file mode 100644 index 000000000000..cb40f22fb00e --- /dev/null +++ b/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js @@ -0,0 +1,335 @@ +/** +* @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 tape = require( 'tape' ); +var trim = require( '@stdlib/string/base/trim' ); +var slice = require( '@stdlib/string/base/slice' ); +var MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' ); +var Uint64 = require( '@stdlib/number/uint64/ctor' ); +var fromString = require( './../lib' ); + + +// VARIABLES // + +var TWO_32 = 0x100000000; // 2^32 + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof fromString, 'function', 'main export is a function' ); + t.end(); +}); + +tape( 'the function returns an unsigned 64-bit integer', function test( t ) { + var x = fromString( '1234' ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + t.end(); +}); + +tape( 'the function throws an error if not provided a string', 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 = fromString( value ); // eslint-disable-line no-unused-vars + }; + } +}); + +tape( 'the function throws an error if not provided a string encoding a nonnegative integer', function test( t ) { + var values; + var i; + + values = [ + '', + '-1', + '0.5', + '++', + '--', + '++1', + '--1', + 'foo', + 'foo1234', + '1234abc', + '0xyab', + '0b123', + '0o789', + '0x', + '0b', + '0o' + ]; + 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 = fromString( value ); // eslint-disable-line no-unused-vars + }; + } +}); + +tape( 'the function correctly handles leading and trailing spaces', function test( t ) { + var values; + var i; + var x; + var y; + + values = [ + ' 1234', + ' 1234', + '1234 ', + '1234 ', + ' 1234 ', + ' 1234 ', + ' 0x1234 ', + ' 0b1010 ', + ' 0o1234 ' + ]; + + for ( i = 0; i < values.length; i++ ) { + x = fromString( values[i] ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + y = fromString( trim( values[i] ) ); + t.deepEqual( x, y, 'returns expected value' ); + } + + t.end(); +}); + +tape( 'the function correctly handles optional plus sign', function test( t ) { + var values; + var i; + var x; + var y; + + values = [ + '+1234', + '+0x1234', + '+0b1010', + '+0o1234' + ]; + + for ( i = 0; i < values.length; i++ ) { + x = fromString( values[i] ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + y = fromString( slice( values[i], 1 ) ); + t.deepEqual( x, y, 'returns expected value' ); + } + + t.end(); +}); + +tape( 'the function correctly parses integers in decimal notation', function test( t ) { + var values; + var i; + var x; + var y; + + values = [ + 0, + 1, + 1234, + 123456789, + 1234567890, + 987654321, + 9876543210, + 1122334455667788, + 8877665544332211, + TWO_32 - 1, + TWO_32, + TWO_32 + 1, + TWO_32 * 2, + MAX_SAFE_INTEGER - 1, + MAX_SAFE_INTEGER + ]; + + for ( i = 0; i < values.length; i++ ) { + x = fromString( values[i].toString( 10 ) ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + y = new Uint64( values[i] ); + t.deepEqual( x, y, 'returns expected value' ); + } + + t.end(); +}); + +tape( 'the function correctly parses integers in hexadecimal notation', function test( t ) { + var values; + var i; + var x; + var y; + + values = [ + 0, + 1, + 1234, + 123456789, + 1234567890, + 987654321, + 9876543210, + 1122334455667788, + 8877665544332211, + TWO_32 - 1, + TWO_32, + TWO_32 + 1, + TWO_32 * 2, + MAX_SAFE_INTEGER - 1, + MAX_SAFE_INTEGER + ]; + + for ( i = 0; i < values.length; i++ ) { + x = fromString( '0x'+values[i].toString( 16 ) ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + y = new Uint64( values[i] ); + t.deepEqual( x, y, 'returns expected value' ); + } + + t.end(); +}); + +tape( 'the function correctly parses integers in binary notation', function test( t ) { + var values; + var i; + var x; + var y; + + values = [ + 0, + 1, + 1234, + 123456789, + 1234567890, + 987654321, + 9876543210, + 1122334455667788, + 8877665544332211, + TWO_32 - 1, + TWO_32, + TWO_32 + 1, + TWO_32 * 2, + MAX_SAFE_INTEGER - 1, + MAX_SAFE_INTEGER + ]; + + for ( i = 0; i < values.length; i++ ) { + x = fromString( '0b'+values[i].toString( 2 ) ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + y = new Uint64( values[i] ); + t.deepEqual( x, y, 'returns expected value' ); + } + + t.end(); +}); + +tape( 'the function correctly parses integers in octal notation', function test( t ) { + var values; + var i; + var x; + var y; + + values = [ + 0, + 1, + 1234, + 123456789, + 1234567890, + 987654321, + 9876543210, + 1122334455667788, + 8877665544332211, + TWO_32 - 1, + TWO_32, + TWO_32 + 1, + TWO_32 * 2, + MAX_SAFE_INTEGER - 1, + MAX_SAFE_INTEGER + ]; + + for ( i = 0; i < values.length; i++ ) { + x = fromString( '0o'+values[i].toString( 8 ) ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + y = new Uint64( values[i] ); + t.deepEqual( x, y, 'returns expected value' ); + } + + t.end(); +}); + +tape( 'the function supports lowercase alphabetic digits and base prefix', function test( t ) { + var values; + var i; + var x; + + values = [ + '0x1234', + '0xabcdef', + '0b1010', + '0o1234' + ]; + + for ( i = 0; i < values.length; i++ ) { + x = fromString( values[i] ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + } + + t.end(); +}); + +tape( 'the function supports uppercase alphabetic digits and base prefix', function test( t ) { + var values; + var i; + var x; + + values = [ + '0X1234', + '0XABCDEF', + '0B1010', + '0O1234' + ]; + + for ( i = 0; i < values.length; i++ ) { + x = fromString( values[i] ); + t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); + } + + t.end(); +}); From 2159defe2310d05c54002a76796634eb784e01c0 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Thu, 28 May 2026 13:36:54 +0600 Subject: [PATCH 08/11] style: resolve lint errors --- 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_pkg_readmes status: passed - task: lint_markdown_docs status: na - 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: passed - 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 --- --- .../@stdlib/number/uint64/from-string/README.md | 6 +++++- .../number/uint64/from-string/examples/index.js | 2 +- .../@stdlib/number/uint64/from-string/lib/parse.js | 14 +++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/README.md b/lib/node_modules/@stdlib/number/uint64/from-string/README.md index 73f2db20e295..3fa67f2ec27e 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/README.md +++ b/lib/node_modules/@stdlib/number/uint64/from-string/README.md @@ -49,11 +49,15 @@ var str = '1234'; var x = fromString( str ); // returns -str = '0x1234567890abcdef' +str = '0x1234567890abcdef'; x = fromString( str ); // returns ``` +
+ + + * * * diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js b/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js index 83435a107812..dd080914c0f3 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js +++ b/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js @@ -18,7 +18,7 @@ 'use strict'; -var fromString = require( '@stdlib/number/uint64/from-string' ); +var fromString = require( './../lib' ); var x = fromString( '1234' ); diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js b/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js index d40c6042583a..91f886cbd37c 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js +++ b/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js @@ -32,6 +32,7 @@ var RE_HEX = /^0[Xx][0-9A-Fa-f]+$/; var RE_BIN = /^0[Bb][01]+$/; var RE_OCT = /^0[Oo][0-7]+$/; + // MAIN // /** @@ -69,10 +70,10 @@ function parseString( value ) { if ( RE_DEC.test( value ) ) { // Chunked parsing for decimal string... - // Process the first chunk so that the remaining chunks are all evenly sized (6 digits): - // Because 6 is the maximum number of digits for a decimal integer that can be safely - // multiplied with a 32-bit integer without precision loss. + // Process the first chunk so that the remaining chunks are all evenly sized (6 digits). + // Because 6 is the maximum number of digits for a decimal integer that can be safely multiplied with a 32-bit integer without precision loss. i = ( value.length % 6 ) || 6; + // If possible, take a bigger chunk: if ( i + 6 <= 9 ) { i += 6; @@ -116,9 +117,12 @@ function parseString( value ) { high = Number( '0o0' + value.slice( i, j ) ); low = Number( '0o' + value.slice( j ) ); - // Since 11 octal digits are equivalent to 33 bits, 1 msb from `low` will be transferred to `high`. - // And the excess bits in `high` and `low` will be truncated via the `>>> 0`. + /* + * Since 11 octal digits are equivalent to 33 bits, 1 msb from `low` will be transferred to `high`. + * And the excess bits in `high` and `low` will be truncated via the `>>> 0` at return. + */ high = ( high << 1 ) | ( low >= TWO_32 ); + return [ high >>> 0, low >>> 0 ]; } From 989dabbd007d4df5778ddc49138450c258db7ab2 Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Sat, 30 May 2026 21:00:06 +0600 Subject: [PATCH 09/11] test: add tests for max 64-bit value and overflow cases --- 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_pkg_readmes status: na - task: lint_markdown_docs status: na - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - 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/from-string/test/test.js | 69 ++++++++++++++++--- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js b/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js index cb40f22fb00e..a0b3b6dd26e3 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js @@ -23,6 +23,7 @@ var tape = require( 'tape' ); var trim = require( '@stdlib/string/base/trim' ); var slice = require( '@stdlib/string/base/slice' ); +var UINT32_MAX = require( '@stdlib/constants/uint32/max' ); var MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' ); var Uint64 = require( '@stdlib/number/uint64/ctor' ); var fromString = require( './../lib' ); @@ -129,7 +130,7 @@ tape( 'the function correctly handles leading and trailing spaces', function tes x = fromString( values[i] ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = fromString( trim( values[i] ) ); - t.deepEqual( x, y, 'returns expected value' ); + t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } t.end(); @@ -152,7 +153,7 @@ tape( 'the function correctly handles optional plus sign', function test( t ) { x = fromString( values[i] ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = fromString( slice( values[i], 1 ) ); - t.deepEqual( x, y, 'returns expected value' ); + t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } t.end(); @@ -167,7 +168,7 @@ tape( 'the function correctly parses integers in decimal notation', function tes values = [ 0, 1, - 1234, + 123456, 123456789, 1234567890, 987654321, @@ -186,7 +187,7 @@ tape( 'the function correctly parses integers in decimal notation', function tes x = fromString( values[i].toString( 10 ) ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = new Uint64( values[i] ); - t.deepEqual( x, y, 'returns expected value' ); + t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } t.end(); @@ -201,7 +202,7 @@ tape( 'the function correctly parses integers in hexadecimal notation', function values = [ 0, 1, - 1234, + 123456, 123456789, 1234567890, 987654321, @@ -220,7 +221,7 @@ tape( 'the function correctly parses integers in hexadecimal notation', function x = fromString( '0x'+values[i].toString( 16 ) ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = new Uint64( values[i] ); - t.deepEqual( x, y, 'returns expected value' ); + t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } t.end(); @@ -235,7 +236,7 @@ tape( 'the function correctly parses integers in binary notation', function test values = [ 0, 1, - 1234, + 123456, 123456789, 1234567890, 987654321, @@ -254,7 +255,7 @@ tape( 'the function correctly parses integers in binary notation', function test x = fromString( '0b'+values[i].toString( 2 ) ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = new Uint64( values[i] ); - t.deepEqual( x, y, 'returns expected value' ); + t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } t.end(); @@ -269,7 +270,7 @@ tape( 'the function correctly parses integers in octal notation', function test( values = [ 0, 1, - 1234, + 123456, 123456789, 1234567890, 987654321, @@ -288,7 +289,7 @@ tape( 'the function correctly parses integers in octal notation', function test( x = fromString( '0o'+values[i].toString( 8 ) ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = new Uint64( values[i] ); - t.deepEqual( x, y, 'returns expected value' ); + t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } t.end(); @@ -333,3 +334,51 @@ tape( 'the function supports uppercase alphabetic digits and base prefix', funct t.end(); }); + +tape( 'the function correctly handles integer values upto 2^64-1', function test( t ) { + var values; + var i; + var x; + var y; + + values = [ + // 2^64 - 1 + '18446744073709551615', + '0xffffffffffffffff', + '0b1111111111111111111111111111111111111111111111111111111111111111', + '0o1777777777777777777777' + ]; + + y = Uint64.of( UINT32_MAX, UINT32_MAX ); + + for ( i = 0; i < values.length; i++ ) { + x = fromString( values[i] ); + t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); + } + + t.end(); +}); + +tape( 'the function performs unsigned 64-bit overflow for integer values greater than 2^64-1', function test( t ) { + var values; + var i; + var x; + var y; + + values = [ + // 2^64 + '18446744073709551616', + '0x10000000000000000', + '0b10000000000000000000000000000000000000000000000000000000000000000', + '0o2000000000000000000000' + ]; + + y = Uint64.of( 0, 0 ); + + for ( i = 0; i < values.length; i++ ) { + x = fromString( values[i] ); + t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); + } + + t.end(); +}); From 400acc768b282e60a966d850bc38af5b4a02d10e Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 12 Jun 2026 04:45:31 +0600 Subject: [PATCH 10/11] chore: rename package --- .../uint64/{from-string => parse}/README.md | 14 ++++---- .../benchmark/benchmark.js | 10 +++--- .../{from-string => parse}/docs/repl.txt | 0 .../docs/types/index.d.ts | 6 ++-- .../{from-string => parse}/docs/types/test.ts | 26 +++++++------- .../{from-string => parse}/examples/index.js | 4 +-- .../{from-string => parse}/lib/index.js | 6 ++-- .../uint64/{from-string => parse}/lib/main.js | 6 ++-- .../{from-string => parse}/lib/parse.js | 0 .../{from-string => parse}/package.json | 2 +- .../{from-string => parse}/test/test.js | 34 +++++++++---------- 11 files changed, 54 insertions(+), 54 deletions(-) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/README.md (91%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/benchmark/benchmark.js (93%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/docs/repl.txt (100%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/docs/types/index.d.ts (90%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/docs/types/test.ts (63%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/examples/index.js (92%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/lib/index.js (85%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/lib/main.js (95%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/lib/parse.js (100%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/package.json (96%) rename lib/node_modules/@stdlib/number/uint64/{from-string => parse}/test/test.js (90%) diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/README.md b/lib/node_modules/@stdlib/number/uint64/parse/README.md similarity index 91% rename from lib/node_modules/@stdlib/number/uint64/from-string/README.md rename to lib/node_modules/@stdlib/number/uint64/parse/README.md index 3fa67f2ec27e..5c178777b6ef 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/README.md +++ b/lib/node_modules/@stdlib/number/uint64/parse/README.md @@ -18,7 +18,7 @@ limitations under the License. --> -# fromString +# parseUint64 > Parse a string as an unsigned 64-bit integer. @@ -37,20 +37,20 @@ limitations under the License. ## Usage ```javascript -var fromString = require( '@stdlib/number/uint64/from-string' ); +var parseUint64 = require( '@stdlib/number/uint64/parse' ); ``` -#### fromString( str ) +#### parseUint64( str ) Parses a string as an unsigned 64-bit integer. ```javascript var str = '1234'; -var x = fromString( str ); +var x = parseUint64( str ); // returns str = '0x1234567890abcdef'; -x = fromString( str ); +x = parseUint64( str ); // returns ``` @@ -84,9 +84,9 @@ x = fromString( str ); ```javascript -var fromString = require( '@stdlib/number/uint64/from-string' ); +var parseUint64 = require( '@stdlib/number/uint64/parse' ); -var x = fromString( '1234' ); +var x = parseUint64( '1234' ); console.log( 'type: %s', typeof x ); // => 'type: object' diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/benchmark/benchmark.js b/lib/node_modules/@stdlib/number/uint64/parse/benchmark/benchmark.js similarity index 93% rename from lib/node_modules/@stdlib/number/uint64/from-string/benchmark/benchmark.js rename to lib/node_modules/@stdlib/number/uint64/parse/benchmark/benchmark.js index c1301b762f2d..d0011b8df23d 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/benchmark/benchmark.js @@ -26,7 +26,7 @@ var format = require( '@stdlib/string/format' ); var MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' ); var Uint64 = require( '@stdlib/number/uint64/ctor' ); var pkg = require( './../package.json' ).name; -var fromString = require( './../lib' ); +var parseUint64 = require( './../lib' ); // MAIN // @@ -45,7 +45,7 @@ bench( pkg, function benchmark( b ) { b.tic(); for ( i = 0; i < b.iterations; i++ ) { - z = fromString( y[ i % y.length ] ); + z = parseUint64( y[ i % y.length ] ); if ( typeof z !== 'object' ) { b.fail( 'should return a Uint64 instance' ); } @@ -72,7 +72,7 @@ bench( format( '%s:hexadecimal', pkg ), function benchmark( b ) { b.tic(); for ( i = 0; i < b.iterations; i++ ) { - z = fromString( y[ i % y.length ] ); + z = parseUint64( y[ i % y.length ] ); if ( typeof z !== 'object' ) { b.fail( 'should return a Uint64 instance' ); } @@ -99,7 +99,7 @@ bench( format( '%s:binary', pkg ), function benchmark( b ) { b.tic(); for ( i = 0; i < b.iterations; i++ ) { - z = fromString( y[ i % y.length ] ); + z = parseUint64( y[ i % y.length ] ); if ( typeof z !== 'object' ) { b.fail( 'should return a Uint64 instance' ); } @@ -126,7 +126,7 @@ bench( format( '%s:octal', pkg ), function benchmark( b ) { b.tic(); for ( i = 0; i < b.iterations; i++ ) { - z = fromString( y[ i % y.length ] ); + z = parseUint64( y[ i % y.length ] ); if ( typeof z !== 'object' ) { b.fail( 'should return a Uint64 instance' ); } diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/docs/repl.txt b/lib/node_modules/@stdlib/number/uint64/parse/docs/repl.txt similarity index 100% rename from lib/node_modules/@stdlib/number/uint64/from-string/docs/repl.txt rename to lib/node_modules/@stdlib/number/uint64/parse/docs/repl.txt diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/parse/docs/types/index.d.ts similarity index 90% rename from lib/node_modules/@stdlib/number/uint64/from-string/docs/types/index.d.ts rename to lib/node_modules/@stdlib/number/uint64/parse/docs/types/index.d.ts index 3a53ce7c6a04..23f4a7b34970 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/number/uint64/parse/docs/types/index.d.ts @@ -29,12 +29,12 @@ import Uint64 = require( '@stdlib/number/uint64/ctor' ); * @returns unsigned 64-bit integer * * @example -* var v = fromString( '5' ); +* var v = parseUint64( '5' ); * // returns */ -declare function fromString( str: string ): Uint64; +declare function parseUint64( str: string ): Uint64; // EXPORTS // -export = fromString; +export = parseUint64; diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/test.ts b/lib/node_modules/@stdlib/number/uint64/parse/docs/types/test.ts similarity index 63% rename from lib/node_modules/@stdlib/number/uint64/from-string/docs/types/test.ts rename to lib/node_modules/@stdlib/number/uint64/parse/docs/types/test.ts index 2035a00b0cd8..284616de7e87 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/docs/types/test.ts +++ b/lib/node_modules/@stdlib/number/uint64/parse/docs/types/test.ts @@ -18,31 +18,31 @@ /* eslint-disable @typescript-eslint/no-unused-expressions */ -import fromString = require( './index' ); +import parseUint64 = require( './index' ); // TESTS // // The function returns an unsigned 64-bit integer... { - fromString( '1234' ); // $ExpectType Uint64 - fromString( '0xabcd' ); // $ExpectType Uint64 - fromString( '0b1010' ); // $ExpectType Uint64 - fromString( '0o1234' ); // $ExpectType Uint64 + parseUint64( '1234' ); // $ExpectType Uint64 + parseUint64( '0xabcd' ); // $ExpectType Uint64 + parseUint64( '0b1010' ); // $ExpectType Uint64 + parseUint64( '0o1234' ); // $ExpectType Uint64 } // The compiler throws an error if the function is provided an argument which is not a string... { - fromString( true ); // $ExpectError - fromString( false ); // $ExpectError - fromString( null ); // $ExpectError - fromString( 123 ); // $ExpectError - fromString( {} ); // $ExpectError - fromString( ( x: number ): number => x ); // $ExpectError + parseUint64( true ); // $ExpectError + parseUint64( false ); // $ExpectError + parseUint64( null ); // $ExpectError + parseUint64( 123 ); // $ExpectError + parseUint64( {} ); // $ExpectError + parseUint64( ( x: number ): number => x ); // $ExpectError } // The compiler throws an error if the function is provided an unsupported number of arguments... { - fromString(); // $ExpectError - fromString( '5', '3' ); // $ExpectError + parseUint64(); // $ExpectError + parseUint64( '5', '3' ); // $ExpectError } diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js b/lib/node_modules/@stdlib/number/uint64/parse/examples/index.js similarity index 92% rename from lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js rename to lib/node_modules/@stdlib/number/uint64/parse/examples/index.js index dd080914c0f3..9646d69f7388 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/examples/index.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/examples/index.js @@ -18,9 +18,9 @@ 'use strict'; -var fromString = require( './../lib' ); +var parseUint64 = require( './../lib' ); -var x = fromString( '1234' ); +var x = parseUint64( '1234' ); console.log( 'type: %s', typeof x ); // => 'type: object' diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/index.js b/lib/node_modules/@stdlib/number/uint64/parse/lib/index.js similarity index 85% rename from lib/node_modules/@stdlib/number/uint64/from-string/lib/index.js rename to lib/node_modules/@stdlib/number/uint64/parse/lib/index.js index cccd1ebe25fe..198289225fd1 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/lib/index.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/lib/index.js @@ -21,12 +21,12 @@ /** * Parse a string as an unsigned 64-bit integer. * -* @module @stdlib/number/uint64/from-string +* @module @stdlib/number/uint64/parse * * @example -* var fromString = require( '@stdlib/number/uint64/from-string' ); +* var parseUint64 = require( '@stdlib/number/uint64/parse' ); * -* var v = fromString( '5' ); +* var v = parseUint64( '5' ); * // returns */ diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js b/lib/node_modules/@stdlib/number/uint64/parse/lib/main.js similarity index 95% rename from lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js rename to lib/node_modules/@stdlib/number/uint64/parse/lib/main.js index df048a268f0b..067f709b5f0c 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/lib/main.js @@ -38,10 +38,10 @@ var parse = require( './parse.js' ); * @returns {Uint64} unsigned 64-bit integer * * @example -* var v = fromString( '5' ); +* var v = parseUint64( '5' ); * // returns */ -function fromString( str ) { +function parseUint64( str ) { var v; if ( !isString( str ) ) { throw new TypeError( format( 'invalid argument. Must provide a string. Value: `%s`.', str ) ); @@ -63,4 +63,4 @@ function fromString( str ) { // EXPORTS // -module.exports = fromString; +module.exports = parseUint64; diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js b/lib/node_modules/@stdlib/number/uint64/parse/lib/parse.js similarity index 100% rename from lib/node_modules/@stdlib/number/uint64/from-string/lib/parse.js rename to lib/node_modules/@stdlib/number/uint64/parse/lib/parse.js diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/package.json b/lib/node_modules/@stdlib/number/uint64/parse/package.json similarity index 96% rename from lib/node_modules/@stdlib/number/uint64/from-string/package.json rename to lib/node_modules/@stdlib/number/uint64/parse/package.json index 8e16d143e9f8..42586090cf0e 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/package.json +++ b/lib/node_modules/@stdlib/number/uint64/parse/package.json @@ -1,5 +1,5 @@ { - "name": "@stdlib/number/uint64/from-string", + "name": "@stdlib/number/uint64/parse", "version": "0.0.0", "description": "Parse a string as an unsigned 64-bit integer.", "license": "Apache-2.0", diff --git a/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js b/lib/node_modules/@stdlib/number/uint64/parse/test/test.js similarity index 90% rename from lib/node_modules/@stdlib/number/uint64/from-string/test/test.js rename to lib/node_modules/@stdlib/number/uint64/parse/test/test.js index a0b3b6dd26e3..5434e1edd905 100644 --- a/lib/node_modules/@stdlib/number/uint64/from-string/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/test/test.js @@ -26,7 +26,7 @@ var slice = require( '@stdlib/string/base/slice' ); var UINT32_MAX = require( '@stdlib/constants/uint32/max' ); var MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' ); var Uint64 = require( '@stdlib/number/uint64/ctor' ); -var fromString = require( './../lib' ); +var parseUint64 = require( './../lib' ); // VARIABLES // @@ -38,12 +38,12 @@ var TWO_32 = 0x100000000; // 2^32 tape( 'main export is a function', function test( t ) { t.ok( true, __filename ); - t.strictEqual( typeof fromString, 'function', 'main export is a function' ); + t.strictEqual( typeof parseUint64, 'function', 'main export is a function' ); t.end(); }); tape( 'the function returns an unsigned 64-bit integer', function test( t ) { - var x = fromString( '1234' ); + var x = parseUint64( '1234' ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); t.end(); }); @@ -68,7 +68,7 @@ tape( 'the function throws an error if not provided a string', function test( t function badValue( value ) { return function badValue() { - var x = fromString( value ); // eslint-disable-line no-unused-vars + var x = parseUint64( value ); // eslint-disable-line no-unused-vars }; } }); @@ -103,7 +103,7 @@ tape( 'the function throws an error if not provided a string encoding a nonnegat function badValue( value ) { return function badValue() { - var x = fromString( value ); // eslint-disable-line no-unused-vars + var x = parseUint64( value ); // eslint-disable-line no-unused-vars }; } }); @@ -127,9 +127,9 @@ tape( 'the function correctly handles leading and trailing spaces', function tes ]; for ( i = 0; i < values.length; i++ ) { - x = fromString( values[i] ); + x = parseUint64( values[i] ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); - y = fromString( trim( values[i] ) ); + y = parseUint64( trim( values[i] ) ); t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } @@ -150,9 +150,9 @@ tape( 'the function correctly handles optional plus sign', function test( t ) { ]; for ( i = 0; i < values.length; i++ ) { - x = fromString( values[i] ); + x = parseUint64( values[i] ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); - y = fromString( slice( values[i], 1 ) ); + y = parseUint64( slice( values[i], 1 ) ); t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } @@ -184,7 +184,7 @@ tape( 'the function correctly parses integers in decimal notation', function tes ]; for ( i = 0; i < values.length; i++ ) { - x = fromString( values[i].toString( 10 ) ); + x = parseUint64( values[i].toString( 10 ) ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = new Uint64( values[i] ); t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); @@ -218,7 +218,7 @@ tape( 'the function correctly parses integers in hexadecimal notation', function ]; for ( i = 0; i < values.length; i++ ) { - x = fromString( '0x'+values[i].toString( 16 ) ); + x = parseUint64( '0x'+values[i].toString( 16 ) ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = new Uint64( values[i] ); t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); @@ -252,7 +252,7 @@ tape( 'the function correctly parses integers in binary notation', function test ]; for ( i = 0; i < values.length; i++ ) { - x = fromString( '0b'+values[i].toString( 2 ) ); + x = parseUint64( '0b'+values[i].toString( 2 ) ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = new Uint64( values[i] ); t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); @@ -286,7 +286,7 @@ tape( 'the function correctly parses integers in octal notation', function test( ]; for ( i = 0; i < values.length; i++ ) { - x = fromString( '0o'+values[i].toString( 8 ) ); + x = parseUint64( '0o'+values[i].toString( 8 ) ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); y = new Uint64( values[i] ); t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); @@ -308,7 +308,7 @@ tape( 'the function supports lowercase alphabetic digits and base prefix', funct ]; for ( i = 0; i < values.length; i++ ) { - x = fromString( values[i] ); + x = parseUint64( values[i] ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); } @@ -328,7 +328,7 @@ tape( 'the function supports uppercase alphabetic digits and base prefix', funct ]; for ( i = 0; i < values.length; i++ ) { - x = fromString( values[i] ); + x = parseUint64( values[i] ); t.strictEqual( x instanceof Uint64, true, 'returns expected value' ); } @@ -352,7 +352,7 @@ tape( 'the function correctly handles integer values upto 2^64-1', function test y = Uint64.of( UINT32_MAX, UINT32_MAX ); for ( i = 0; i < values.length; i++ ) { - x = fromString( values[i] ); + x = parseUint64( values[i] ); t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } @@ -376,7 +376,7 @@ tape( 'the function performs unsigned 64-bit overflow for integer values greater y = Uint64.of( 0, 0 ); for ( i = 0; i < values.length; i++ ) { - x = fromString( values[i] ); + x = parseUint64( values[i] ); t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); } From 203bdc127810360f3dc0f21ffa46b1bf547bc1fc Mon Sep 17 00:00:00 2001 From: Abdul Kaium Date: Fri, 12 Jun 2026 04:46:37 +0600 Subject: [PATCH 11/11] feat: reimplement parse logic with arbitrary radix support --- 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_pkg_readmes status: na - task: lint_markdown_docs status: na - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: na - 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 --- --- .../uint64/parse/benchmark/benchmark.js | 109 ++------- .../number/uint64/parse/docs/types/index.d.ts | 13 +- .../@stdlib/number/uint64/parse/lib/index.js | 13 +- .../@stdlib/number/uint64/parse/lib/main.js | 98 +++++++- .../@stdlib/number/uint64/parse/lib/parse.js | 220 +++++++++++------- .../@stdlib/number/uint64/parse/test/test.js | 19 +- 6 files changed, 275 insertions(+), 197 deletions(-) diff --git a/lib/node_modules/@stdlib/number/uint64/parse/benchmark/benchmark.js b/lib/node_modules/@stdlib/number/uint64/parse/benchmark/benchmark.js index d0011b8df23d..bdec8fb91917 100644 --- a/lib/node_modules/@stdlib/number/uint64/parse/benchmark/benchmark.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/benchmark/benchmark.js @@ -22,7 +22,7 @@ var bench = require( '@stdlib/bench' ); var discreteUniform = require( '@stdlib/random/array/discrete-uniform' ); -var format = require( '@stdlib/string/format' ); +var floor = require( '@stdlib/math/base/special/floor' ); var MAX_SAFE_INTEGER = require( '@stdlib/constants/float64/max-safe-integer' ); var Uint64 = require( '@stdlib/number/uint64/ctor' ); var pkg = require( './../package.json' ).name; @@ -32,107 +32,36 @@ var parseUint64 = require( './../lib' ); // MAIN // bench( pkg, function benchmark( b ) { - var x; - var y; - var z; + var values; + var radix; + var N; + var M; + var a; var i; - - x = discreteUniform( 100, 0, MAX_SAFE_INTEGER ); - y = []; - for ( i = 0; i < x.length; i++ ) { - y.push( x[i].toString() ); - } - - b.tic(); - for ( i = 0; i < b.iterations; i++ ) { - z = parseUint64( y[ i % y.length ] ); - if ( typeof z !== 'object' ) { - b.fail( 'should return a Uint64 instance' ); - } - } - b.toc(); - if ( !( z instanceof Uint64 ) ) { - b.fail( 'should return a Uint64 instance' ); - } - b.pass( 'benchmark finished' ); - b.end(); -}); - -bench( format( '%s:hexadecimal', pkg ), function benchmark( b ) { - var x; - var y; - var z; - var i; - - x = discreteUniform( 100, 0, MAX_SAFE_INTEGER ); - y = []; - for ( i = 0; i < x.length; i++ ) { - y.push( '0x'+x[i].toString( 16 ) ); - } - - b.tic(); - for ( i = 0; i < b.iterations; i++ ) { - z = parseUint64( y[ i % y.length ] ); - if ( typeof z !== 'object' ) { - b.fail( 'should return a Uint64 instance' ); - } - } - b.toc(); - if ( !( z instanceof Uint64 ) ) { - b.fail( 'should return a Uint64 instance' ); - } - b.pass( 'benchmark finished' ); - b.end(); -}); - -bench( format( '%s:binary', pkg ), function benchmark( b ) { + var j; var x; - var y; - var z; - var i; - - x = discreteUniform( 100, 0, MAX_SAFE_INTEGER ); - y = []; - for ( i = 0; i < x.length; i++ ) { - y.push( '0b'+x[i].toString( 2 ) ); - } - b.tic(); - for ( i = 0; i < b.iterations; i++ ) { - z = parseUint64( y[ i % y.length ] ); - if ( typeof z !== 'object' ) { - b.fail( 'should return a Uint64 instance' ); + N = 100; + x = discreteUniform( N, 0, MAX_SAFE_INTEGER ); + values = []; + for ( radix = 2; radix <= 36; radix++ ) { + for ( i = 0; i < N; i++ ) { + values.push( x[i].toString( radix ) ); } } - b.toc(); - if ( !( z instanceof Uint64 ) ) { - b.fail( 'should return a Uint64 instance' ); - } - b.pass( 'benchmark finished' ); - b.end(); -}); - -bench( format( '%s:octal', pkg ), function benchmark( b ) { - var x; - var y; - var z; - var i; - - x = discreteUniform( 100, 0, MAX_SAFE_INTEGER ); - y = []; - for ( i = 0; i < x.length; i++ ) { - y.push( '0o'+x[i].toString( 8 ) ); - } + M = values.length; b.tic(); for ( i = 0; i < b.iterations; i++ ) { - z = parseUint64( y[ i % y.length ] ); - if ( typeof z !== 'object' ) { + j = i % M; + radix = 2 + floor( j / N ); + a = parseUint64( values[ j ], radix ); + if ( typeof a !== 'object' ) { b.fail( 'should return a Uint64 instance' ); } } b.toc(); - if ( !( z instanceof Uint64 ) ) { + if ( !( a instanceof Uint64 ) ) { b.fail( 'should return a Uint64 instance' ); } b.pass( 'benchmark finished' ); diff --git a/lib/node_modules/@stdlib/number/uint64/parse/docs/types/index.d.ts b/lib/node_modules/@stdlib/number/uint64/parse/docs/types/index.d.ts index 23f4a7b34970..a045c72f4679 100644 --- a/lib/node_modules/@stdlib/number/uint64/parse/docs/types/index.d.ts +++ b/lib/node_modules/@stdlib/number/uint64/parse/docs/types/index.d.ts @@ -29,8 +29,17 @@ import Uint64 = require( '@stdlib/number/uint64/ctor' ); * @returns unsigned 64-bit integer * * @example -* var v = parseUint64( '5' ); -* // returns +* var v = parseUint64( '1234' ); +* // returns [ 1234n ] +* +* v = parseUint64( '18446744073709551615' ); +* // returns [ 18446744073709551615n ] +* +* v = parseUint64( '0xffffffffffffffff' ); +* // returns [ 18446744073709551615n ] +* +* v = parseUint64( '3w5e11264sgsf', 36 ); +* // returns [ 18446744073709551615n ] */ declare function parseUint64( str: string ): Uint64; diff --git a/lib/node_modules/@stdlib/number/uint64/parse/lib/index.js b/lib/node_modules/@stdlib/number/uint64/parse/lib/index.js index 198289225fd1..d9adee21df44 100644 --- a/lib/node_modules/@stdlib/number/uint64/parse/lib/index.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/lib/index.js @@ -26,8 +26,17 @@ * @example * var parseUint64 = require( '@stdlib/number/uint64/parse' ); * -* var v = parseUint64( '5' ); -* // returns +* var v = parseUint64( '1234' ); +* // returns [ 1234n ] +* +* v = parseUint64( '18446744073709551615' ); +* // returns [ 18446744073709551615n ] +* +* v = parseUint64( '0xffffffffffffffff' ); +* // returns [ 18446744073709551615n ] +* +* v = parseUint64( '3w5e11264sgsf', 36 ); +* // returns [ 18446744073709551615n ] */ // MAIN // diff --git a/lib/node_modules/@stdlib/number/uint64/parse/lib/main.js b/lib/node_modules/@stdlib/number/uint64/parse/lib/main.js index 067f709b5f0c..4ddcb2e82984 100644 --- a/lib/node_modules/@stdlib/number/uint64/parse/lib/main.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/lib/main.js @@ -20,7 +20,10 @@ // MODULES // +var isBetween = require( '@stdlib/assert/is-between' ); +var isInteger = require( '@stdlib/assert/is-integer' ).isPrimitive; var isString = require( '@stdlib/assert/is-string' ).isPrimitive; +var isEmptyString = require( '@stdlib/assert/is-empty-string' ).isPrimitive; var Uint64 = require( '@stdlib/number/uint64/ctor' ); var trim = require( '@stdlib/string/base/trim' ); var slice = require( '@stdlib/string/base/slice' ); @@ -28,36 +31,109 @@ var format = require( '@stdlib/string/format' ); var parse = require( './parse.js' ); +// VARIABLES // + +var RE_HEX = /^0[Xx]/; +var RE_BIN = /^0[Bb]/; +var RE_OCT = /^0[Oo]/; +var DIGITS = '0123456789abcdefghijklmnopqrstuvwxyz'; +var WORKSPACE = [ 0, 0 ]; + + // MAIN // /** * Parses a string as an unsigned 64-bit integer. * * @param {string} str - string representation of a nonnegative integer -* @throws {TypeError} must provide a string encoding a nonnegative integer +* @param {PositiveInteger} [radix=10] - radix (base) to use for string conversion (2-36) +* @throws {TypeError} must provide a string +* @throws {RangeError} must provide an integer on the interval [2, 36] +* @throws {Error} must provide a string encoding a nonnegative integer * @returns {Uint64} unsigned 64-bit integer * * @example -* var v = parseUint64( '5' ); -* // returns +* var v = parseUint64( '1234' ); +* // returns [ 1234n ] +* +* v = parseUint64( '18446744073709551615' ); +* // returns [ 18446744073709551615n ] +* +* v = parseUint64( '0xffffffffffffffff' ); +* // returns [ 18446744073709551615n ] +* +* v = parseUint64( '3w5e11264sgsf', 36 ); +* // returns [ 18446744073709551615n ] */ -function parseUint64( str ) { +function parseUint64( str, radix ) { + var validChars; + var reInv; + var rad; var v; + var i; + if ( !isString( str ) ) { throw new TypeError( format( 'invalid argument. Must provide a string. Value: `%s`.', str ) ); } + v = trim( str ); - if ( v[ 0 ] === '-' ) { - throw new TypeError( format( 'invalid argument. Must provide a string encoding a nonnegative integer. Value: `%s`.', str ) ); + if ( v[0] === '-' ) { + throw new Error( format( 'invalid argument. Must provide a string encoding a nonnegative integer. Value: `%s`.', str ) ); } - if ( v[ 0 ] === '+' ) { + + if ( v[0] === '+' ) { v = slice( v, 1 ); } - v = parse( v ); - if ( v[ 0 ] === -1 ) { - throw new TypeError( format( 'invalid argument. Must provide a string encoding a nonnegative integer. Value: `%s`.', str ) ); + + if ( arguments.length < 2 ) { + if ( RE_BIN.test( v ) ) { + rad = 2; + } else if ( RE_OCT.test( v ) ) { + rad = 8; + } else if ( RE_HEX.test( v ) ) { + rad = 16; + } else { + rad = 10; + } + + if ( rad !== 10 ) { + v = slice( v, 2 ); + } + } else if ( !isInteger( radix ) ) { + throw new TypeError( format( 'invalid argument. Must provide an integer. Value: `%s`.', radix ) ); + } else if ( isBetween( radix, 2, 36 ) ) { + rad = radix; + } else { + throw new RangeError( format( 'invalid argument. Must provide an integer on the interval [2, 36]. Value: `%s`.', radix ) ); + } + + if ( isEmptyString( v ) ) { + throw new Error( format( 'invalid argument. Must provide a non-empty string encoding a nonnegative integer. Value: `%s`.', str ) ); + } + + // Trim leading zeros + i = 0; + while ( ( i < v.length-1 ) && ( v[i] === '0' ) ) { + i += 1; + } + v = slice( v, i ); + + // Validate digits with respect to radix + validChars = slice( DIGITS, 0, rad ); + reInv = new RegExp( format( '[^%s]', validChars ), 'i' ); + if ( reInv.test( v ) ) { + throw new Error( format( 'invalid argument. Cannot parse a string containing invalid characters. Value: `%s`.', str ) ); + } + + // Reset the workspace: + WORKSPACE[ 0 ] = 0; + WORKSPACE[ 1 ] = 0; + parse( v, rad, WORKSPACE ); + + if ( WORKSPACE[ 0 ] === -1 ) { + throw new RangeError( format( 'invalid argument. Must provide a string encoding a nonnegative integer smaller than 2^64. Value: `%s`.', str ) ); } - return Uint64.from( v ); + return Uint64.from( WORKSPACE ); } diff --git a/lib/node_modules/@stdlib/number/uint64/parse/lib/parse.js b/lib/node_modules/@stdlib/number/uint64/parse/lib/parse.js index 91f886cbd37c..61b80dbb94d9 100644 --- a/lib/node_modules/@stdlib/number/uint64/parse/lib/parse.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/lib/parse.js @@ -18,118 +18,170 @@ 'use strict'; -// MODULES // - -var max = require( '@stdlib/math/base/special/fast/max' ); -var Number = require( '@stdlib/number/ctor' ); - - // VARIABLES // var TWO_32 = 0x100000000; // 2^32 -var RE_DEC = /^[0-9]+$/; -var RE_HEX = /^0[Xx][0-9A-Fa-f]+$/; -var RE_BIN = /^0[Bb][01]+$/; -var RE_OCT = /^0[Oo][0-7]+$/; - -// MAIN // +/* eslint-disable array-element-newline */ + +// TODO: Explain derivation + +// Chunk sizes for optimal parsing in within JavaScript's integer 53-bit precision. +var CHUNKMAP = [ + // , , // radix + 53, 11, 2048, // 2 + 33, 8, 6561, // 3 + 26, 6, 4096, // 4 + 22, 6, 15625, // 5 + 20, 5, 7776, // 6 + 18, 5, 16807, // 7 + 17, 5, 32768, // 8 + 16, 5, 59049, // 9 + 15, 5, 100000, // 10 + 15, 4, 14641, // 11 + 14, 4, 20736, // 12 + 14, 4, 28561, // 13 + 13, 4, 38416, // 14 + 13, 4, 50625, // 15 + 13, 3, 4096, // 16 + 12, 4, 83521, // 17 + 12, 4, 104976, // 18 + 12, 4, 130321, // 19 + 12, 3, 8000, // 20 + 12, 3, 9261, // 21 + 11, 4, 234256, // 22 + 11, 4, 279841, // 23 + 11, 3, 13824, // 24 + 11, 3, 15625, // 25 + 11, 3, 17576, // 26 + 11, 3, 19683, // 27 + 11, 3, 21952, // 28 + 10, 4, 707281, // 29 + 10, 4, 810000, // 30 + 10, 3, 29791, // 31 + 10, 3, 32768, // 32 + 10, 3, 35937, // 33 + 10, 3, 39304, // 34 + 10, 3, 42875, // 35 + 10, 3, 46656 // 36 +]; + +/* eslint-enable array-element-newline */ /** -* Parses an arbitrary-length string representation of an unsigned integer and converts to a double word representation of unsigned 64 bit integer. +* Parses a string representation of an unsigned 64-bit integer and converts to a double word representation as two 32-bit unsigned integers. * * @private * @param {string} value - string representation of an unsigned integer +* @param {PositiveInteger} radix - radix (base) to use for string conversion (2-36) +* @param {PositiveInteger} len1 - max length of the first chunk +* @param {PositiveInteger} len2 - max length of the second chunk +* @param {PositiveInteger} mult - multiplier for the place value calculation (radix raised to the power of len2) +* @param {Array} out - output array * @returns {Array} high and low words of an unsigned 64-bit integer * * @example -* var v = parseString( '0xffffffff0000ffff' ); -* // returns [ 4294967295, 65535 ] -* -* v = parseString( '0x1ffffffff0000ffff' ); -* // returns [ 4294967295, 65535 ] -* -* v = parseString( '0xffff' ); -* // returns [ 0, 65535 ] +* var v = chunkedParse( '1111111111111111111111111111111111111111111111111111111111111111', 2, CHUNKMAP[0], CHUNKMAP[1], CHUNKMAP[2], [ 0, 0 ] ); +* // returns [ 4294967295, 4294967295 ] * -* v = parseString( '0o100' ); -* // returns [ 0, 64 ] +* v = chunkedParse( '18446744073709551615', 10, CHUNKMAP[24], CHUNKMAP[25], CHUNKMAP[26], [ 0, 0 ] ); +* // returns [ 4294967295, 4294967295 ] * -* v = parseString( '0b100' ); -* // returns [ 0, 4 ] +* v = chunkedParse( '3w5e11264sgsf', 36, CHUNKMAP[102], CHUNKMAP[103], CHUNKMAP[104], [ 0, 0 ] ); +* // returns [ 4294967295, 4294967295 ] * -* v = parseString( '4294967296' ); -* // returns [ 1, 0 ] */ -function parseString( value ) { - var high; - var low; - var tmp; - var j; - var i; - - if ( RE_DEC.test( value ) ) { - // Chunked parsing for decimal string... - // Process the first chunk so that the remaining chunks are all evenly sized (6 digits). - // Because 6 is the maximum number of digits for a decimal integer that can be safely multiplied with a 32-bit integer without precision loss. - i = ( value.length % 6 ) || 6; - - // If possible, take a bigger chunk: - if ( i + 6 <= 9 ) { - 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 >>> 0, low >>> 0 ]; +function chunkedParse( value, radix, len1, len2, mult, out ) { + var chunk1; + var chunk2; + var hi; + var lo; + + if ( value.length <= len1 ) { + // Parse in a single pass if value is within MAX_SAFE_INTEGER + chunk1 = parseInt( value, radix ); + } else { + // Otherwise use a big chunk (start-aligned) and a small chunk (end-aligned) + chunk1 = parseInt( value.slice( 0, -len2 ), radix ); // Everything until last `len2` digits + chunk2 = parseInt( value.slice( -len2 ), radix ); // `len2` digits from the end } - if ( RE_HEX.test( value ) ) { - j = max( 2, value.length - 8 ); - i = max( 2, value.length - 16 ); - return [ - Number( '0x0' + value.slice( i, j ) ) >>> 0, - Number( '0x' + value.slice( j ) ) >>> 0 - ]; - } + hi = ( chunk1 / TWO_32 ) >>> 0; // Integer division by 2^32 + lo = chunk1 >>> 0; // 32-bit truncation - if ( RE_BIN.test( value ) ) { - j = max( 2, value.length - 32 ); - i = max( 2, value.length - 64 ); - return [ - Number( '0b0' + value.slice( i, j ) ) >>> 0, - Number( '0b' + value.slice( j ) ) >>> 0 - ]; + // Process chunk2 if applicable + if ( value.length > len1 ) { + lo = ( lo * mult ) + chunk2; + hi = ( hi * mult ) + ( ( lo / TWO_32 ) >>> 0 ); + lo >>>= 0; // 32-bit truncation + + if ( hi >= TWO_32 ) { + // Too big for Uint64 + out[0] = out[1] = -1; + return out; + } } - if ( RE_OCT.test( value ) ) { - j = max( 2, value.length - 11 ); - i = max( 2, value.length - 22 ); + out[0] = hi; + out[1] = lo; + return out; +} + - high = Number( '0o0' + value.slice( i, j ) ); - low = Number( '0o' + value.slice( j ) ); +// MAIN // - /* - * Since 11 octal digits are equivalent to 33 bits, 1 msb from `low` will be transferred to `high`. - * And the excess bits in `high` and `low` will be truncated via the `>>> 0` at return. - */ - high = ( high << 1 ) | ( low >= TWO_32 ); +/** +* Parses a string representation of an unsigned 64-bit integer and converts to a double word representation as two 32-bit unsigned integers. +* +* @private +* @param {string} value - string representation of an unsigned integer +* @param {PositiveInteger} radix - radix (base) to use for string conversion (2-36) +* @param {Array} out - output array +* @returns {Array} high and low words of an unsigned 64-bit integer +* +* @example +* var v = parse( '18446744073709551615', 10, [ 0, 0 ] ); +* // returns [ 4294967295, 4294967295 ] +* +* v = parse( 'ffffffffffffffff', 16, [ 0, 0] ); +* // returns [ 4294967295, 4294967295 ] +* +* v = parse( '3w5e11264sgsf', 36, [ 0, 0] ); +* // returns [ 4294967295, 4294967295 ] +*/ +function parse( value, radix, out ) { + var len1; + var len2; + var mult; + var idx; + + // Compute the index into a pre-computed strided table: + idx = 3 * ( radix-2 ); + + // Use a pre-computed table to select chunk lengths and the multiplier + len1 = CHUNKMAP[ idx ]; + len2 = CHUNKMAP[ idx+1 ]; + mult = CHUNKMAP[ idx+2 ]; + + if ( value.length > len1+len2 ) { + // Too big for Uint64 + out[0] = out[1] = -1; + return out; + } - return [ high >>> 0, low >>> 0 ]; + // Fast path for bases 2, 4, and 16 due to evenly splittable 32-bit halves + if ( radix === 2 || radix === 4 || radix === 16 ) { + len1 = len2 = ( len1 + len2 ) / 2; + out[0] = parseInt( '0' + value.slice( 0, -len2 ), radix ); + out[1] = parseInt( value.slice( -len2 ), radix ); + return out; } - return [ -1, -1 ]; + // General path for other bases + return chunkedParse( value, radix, len1, len2, mult, out ); } // EXPORTS // -module.exports = parseString; +module.exports = parse; diff --git a/lib/node_modules/@stdlib/number/uint64/parse/test/test.js b/lib/node_modules/@stdlib/number/uint64/parse/test/test.js index 5434e1edd905..e001fafa7f11 100644 --- a/lib/node_modules/@stdlib/number/uint64/parse/test/test.js +++ b/lib/node_modules/@stdlib/number/uint64/parse/test/test.js @@ -96,7 +96,7 @@ tape( 'the function throws an error if not provided a string encoding a nonnegat '0o' ]; for ( i = 0; i < values.length; i++ ) { - t.throws( badValue( values[i] ), TypeError, 'throws an error when provided '+values[i] ); + t.throws( badValue( values[i] ), Error, 'throws an error when provided '+values[i] ); } t.end(); @@ -359,11 +359,9 @@ tape( 'the function correctly handles integer values upto 2^64-1', function test t.end(); }); -tape( 'the function performs unsigned 64-bit overflow for integer values greater than 2^64-1', function test( t ) { +tape( 'the function throws an error for integer values greater than 2^64-1', function test( t ) { var values; var i; - var x; - var y; values = [ // 2^64 @@ -373,12 +371,17 @@ tape( 'the function performs unsigned 64-bit overflow for integer values greater '0o2000000000000000000000' ]; - y = Uint64.of( 0, 0 ); - for ( i = 0; i < values.length; i++ ) { - x = parseUint64( values[i] ); - t.strictEqual( x.toString(), y.toString(), 'returns expected value' ); + t.throws( badValue( values[i] ), Error, 'throws an error when provided '+values[i] ); } t.end(); + + function badValue( value ) { + return function badValue() { + var x = parseUint64( value ); // eslint-disable-line no-unused-vars + }; + } }); + +// FIXME: Add additional tests