UNPKG

1.38 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.bnSqrt = bnSqrt;
7
8var _assert = require("../assert");
9
10var _bn = require("./bn");
11
12var _consts = require("./consts");
13
14var _toBn = require("./toBn");
15
16// Copyright 2017-2022 @polkadot/util authors & contributors
17// SPDX-License-Identifier: Apache-2.0
18const SQRT_MAX_SAFE_INTEGER = new _bn.BN(94906265);
19/**
20 * @name bnSqrt
21 * @summary Calculates the integer square root of a BN
22 * @example
23 * <BR>
24 *
25 * ```javascript
26 * import BN from 'bn.js';
27 * import { bnSqrt } from '@polkadot/util';
28 *
29 * bnSqrt(new BN(16)).toString(); // => '4'
30 * ```
31 */
32
33function bnSqrt(value) {
34 const n = (0, _toBn.bnToBn)(value);
35 (0, _assert.assert)(n.gte(_consts.BN_ZERO), 'square root of negative numbers is not supported'); // https://stackoverflow.com/questions/53683995/javascript-big-integer-square-root/
36 // shortcut <= 2^53 - 1 to use the JS utils
37
38 if (n.lte(_consts.BN_MAX_INTEGER)) {
39 return new _bn.BN(Math.floor(Math.sqrt(n.toNumber())));
40 } // Use sqrt(MAX_SAFE_INTEGER) as starting point. since we already know the
41 // output will be larger than this, we expect this to be a safe start
42
43
44 let x0 = SQRT_MAX_SAFE_INTEGER.clone();
45
46 while (true) {
47 const x1 = n.div(x0).iadd(x0).ishrn(1);
48
49 if (x0.eq(x1) || x0.eq(x1.sub(_consts.BN_ONE))) {
50 return x0;
51 }
52
53 x0 = x1;
54 }
55}
\No newline at end of file