UNPKG

locutus

Version:

Locutus other languages' standard libraries to JavaScript for fun and educational purposes

46 lines (45 loc) 1.64 kB
const MAX_SAFE_ROOT = BigInt(Number.MAX_SAFE_INTEGER); const FIRST_UNSAFE_ROOT_SQUARED = (MAX_SAFE_ROOT + 1n) * (MAX_SAFE_ROOT + 1n); export function isqrt(n) { // discuss at: https://locutus.io/python/isqrt/ // parity verified: Python 3.12 // original by: Kevin van Zonneveld (https://kvz.io) // note 1: Returns the integer square root, rounding down to the nearest whole number. // example 1: isqrt(15) // returns 1: 3 // example 2: isqrt(16) // returns 2: 4 // example 3: isqrt(0) // returns 3: 0 if (typeof n === 'string' && /^[-+]?\d+$/.test(n.trim())) { const parsed = BigInt(n); if (parsed < 0n) { throw new Error('isqrt() only accepts non-negative integers'); } if (parsed >= FIRST_UNSAFE_ROOT_SQUARED) { throw new RangeError('isqrt() only supports roots within JS safe integer precision'); } const root = bigintSqrt(parsed); if (root > MAX_SAFE_ROOT) { throw new RangeError('isqrt() only supports roots within JS safe integer precision'); } return Number(root); } const value = Number(n); if (!Number.isFinite(value) || !Number.isSafeInteger(value) || value < 0) { throw new Error('isqrt() only accepts non-negative integers'); } return Math.floor(Math.sqrt(value)); } function bigintSqrt(value) { if (value < 2n) { return value; } let x0 = value; let x1 = (x0 + 1n) >> 1n; while (x1 < x0) { x0 = x1; x1 = (x1 + value / x1) >> 1n; } return x0; }