UNPKG

1.35 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.bnSqrt = void 0;
4const bn_js_1 = require("./bn.js");
5const consts_js_1 = require("./consts.js");
6const toBn_js_1 = require("./toBn.js");
7/**
8 * @name bnSqrt
9 * @summary Calculates the integer square root of a BN
10 * @example
11 * <BR>
12 *
13 * ```javascript
14 * import BN from 'bn.js';
15 * import { bnSqrt } from '@polkadot/util';
16 *
17 * bnSqrt(new BN(16)).toString(); // => '4'
18 * ```
19 */
20function bnSqrt(value) {
21 const n = (0, toBn_js_1.bnToBn)(value);
22 if (n.isNeg()) {
23 throw new Error('square root of negative numbers is not supported');
24 }
25 // https://stackoverflow.com/questions/53683995/javascript-big-integer-square-root/
26 // shortcut <= 2^53 - 1 to use the JS utils
27 if (n.lte(consts_js_1.BN_MAX_INTEGER)) {
28 // ~~ More performant version of Math.floor
29 return new bn_js_1.BN(~~Math.sqrt(n.toNumber()));
30 }
31 // Use sqrt(MAX_SAFE_INTEGER) as starting point. since we already know the
32 // output will be larger than this, we expect this to be a safe start
33 let x0 = consts_js_1.BN_SQRT_MAX_INTEGER.clone();
34 while (true) {
35 const x1 = n.div(x0).iadd(x0).ishrn(1);
36 if (x0.eq(x1) || x0.eq(x1.sub(consts_js_1.BN_ONE))) {
37 return x0;
38 }
39 x0 = x1;
40 }
41}
42exports.bnSqrt = bnSqrt;