UNPKG

1.01 kBJavaScriptView Raw
1import { BigInt } from '@polkadot/x-bigint';
2import { _0n, _1n, _2pow53n, _sqrt2pow53n } from './consts.js';
3import { nToBigInt } from './toBigInt.js';
4/**
5 * @name nSqrt
6 * @summary Calculates the integer square root of a bigint
7 */
8export function nSqrt(value) {
9 const n = nToBigInt(value);
10 if (n < _0n) {
11 throw new Error('square root of negative numbers is not supported');
12 }
13 // https://stackoverflow.com/questions/53683995/javascript-big-integer-square-root/
14 // shortcut <= 2^53 - 1 to use the JS utils
15 if (n <= _2pow53n) {
16 // ~~ is more performant that Math.floor
17 return BigInt(~~Math.sqrt(Number(n)));
18 }
19 // Use sqrt(MAX_SAFE_INTEGER) as starting point. since we already know the
20 // output will be larger than this, we expect this to be a safe start
21 let x0 = _sqrt2pow53n;
22 while (true) {
23 const x1 = ((n / x0) + x0) >> _1n;
24 if (x0 === x1 || (x0 === (x1 - _1n))) {
25 return x0;
26 }
27 x0 = x1;
28 }
29}