JavaScript - BigInt
BigInt
JavaScript 中的 BigInt 数据类型是一种数值原语,可以表示任意大小的整数。这与 Number 数据类型不同,后者只能表示 -(253 - 1) 到 253 - 1 之间的整数。
JavaScript 用于支持动态 Web 应用程序,传统上根据广泛采用的 IEEE-754 标准的双精度浮点格式使用 Number 类型进行数值表示。该标准施加了一个重要的限制:它最多只能精确表示 253 - 1 作为其最大安全整数。然而,超过这个数值阈值会开始降低数值的保真度,并在关键计算中引入潜在的误差。
JavaScript 引入了 BigInt 数据类型来应对这些限制;顾名思义,BigInt 解决了有限精度的缺点。这种能力在各种场景中都不可或缺,尤其是在密码算法、金融计算以及要求极高精度的复杂数学运算等领域:它允许以任意精度表示整数,这是一个显著的进步。
声明和初始化
您可以使用数字字面量后跟 n 后缀或使用 BigInt() 构造函数来创建 BigInt。
const bigIntLiteral = 123n; const anotherBigInt = BigInt(456);
需要注意的是,如果尝试混合使用常规数字和 BigInt 类型,且未进行显式转换,则可能会导致错误。
基本运算
BigInt 支持标准算术运算,例如加法、减法、乘法和除法。执行运算时,两个操作数都必须为 BigInt 类型。
const a = 123n; const b = 456n; const sum = a + b; // 579n const product = a * b; // 56088n
比较
可以使用标准比较运算符比较 BigInt 值,例如 <、>、<=、>= 和 ===。
const a = 123n; const b = 456n; a > b; // false a === b; // false
转换
可以在 BigInt 和常规数字之间转换,但请注意,对于非常大的 BigInt 值,可能会有精度损失。
const bigIntValue = BigInt("12345678901234567890");
const regularNumber = Number(bigIntValue);
const bigIntValue = BigInt("12345678901234567890");
const regularNumber = Number(bigIntValue);
示例
示例 1:简单的 BigInt 运算
在本例中,我们演示了两个 BigInt 数 num1 和 num2 的加法和乘法,它们的值分别为 123n 和 456n。BigInt 能够精确表示大整数值,且不会损失精度,从而克服了常规 JavaScript 数字的一个潜在缺陷。
<!DOCTYPE html>
<html>
<body>
<h2>Simple BigInt Arithmetic</h2>
<p id="result"></p>
<script>
const num1 = 123n;
const num2 = 456n;
const sum = num1 + num2;
const product = num1 * num2;
document.addEventListener("DOMContentLoaded", function () {
document.getElementById("result").innerText =
`Sum of ${num1} & ${num2} is ${sum} and their product: ${product}`;
});
</script>
</body>
</html>
示例 2:使用 BigInt 的斐波那契数列生成器
斐波那契数列:一系列数字,其中每个数字都是其前两个数字之和;使用 BigInt 来处理超出常规 JavaScript 数字精度限制的较大值。通过 generateFibonacci 函数,数组可存储这些序列值,即使对于数值量级较大的项也能保证精确计算。
<!DOCTYPE html>
<html>
<body>
<h2>Fibonacci Sequence</h2>
<p id="result"></p>
<script>
function generateFibonacci(n) {
const sequence = [0n, 1n];
for (let i = 2; i <= n; i++) {
sequence[i] = sequence[i - 1] + sequence[i - 2];
}
return sequence;
}
document.addEventListener("DOMContentLoaded", function () {
const result = generateFibonacci(20);
document.getElementById("result").innerText = "Fibonacci Sequence of 1st 20 terms: " + result.join(", ");
});
</script>
</body>
</html>
示例 3:使用 BigInt 计算阶乘
阶乘是所有小于或等于指定数字的正整数的乘积。为了计算阶乘,我们使用了 BigInt。对于像 5 和 10 这样的小数,使用普通数字就可以了,但当我们需要计算 10000 的阶乘时,输出结果会非常庞大。因此,BigInt 派上了用场。在本例中,我们借助循环计算 20n 的阶乘。
<!DOCTYPE html>
<html>
<body>
<h2>Factorial of a Large Number</h2>
<p id="result"></p>
<script>
function calculateFactorial() {
const num = 20n; // 计算 20 的阶乘
let result = 1n;
for (let i = 2n; i <= num; i++) {
result *= i;
}
document.getElementById("result").innerText = "Factorial of 20 is " + result;
}
document.addEventListener("DOMContentLoaded", function () {
calculateFactorial();
});
</script>
</body>
</html>
示例 4:BigInt 颜色方块
本例中使用 BigInt,在预定义参数范围内生成随机颜色,并将其应用于 colorSquare 进行演示。随机颜色的生成涉及乘法运算:将通过 Math.random() 获取的 0 到 1 之间的浮点数乘以最大颜色值。随后,我们通过 Math.floor() 将结果向下舍入到最接近的整数,然后使用 BigInt() 将其转换为 BigInt。生成的 BigInt 将被转换为十六进制字符串并返回。
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: Arial, sans-serif;
}
#colorSquare {
width: 400px;
height: 200px;
border: 2px solid #000;
}
</style>
</head>
<body>
<h2>BigInt Color Example</h2>
<div id="colorSquare"></div>
<script>
function generateRandomColor() {
const maxColorValue = 16777215n; // 0xFFFFFF in hexadecimal
const randomColor = BigInt(Math.floor(Math.random() * Number(maxColorValue)));
return `#${randomColor.toString(16).padStart(6, '0')}`;
}
const colorSquare = document.getElementById('colorSquare');
colorSquare.style.backgroundColor = generateRandomColor();
</script>
</body>
</html>
BigInt 的错误处理
此代码演示了一个将 BigInt 与常规数字相加的特殊情况。在 JavaScript 中,我们需要显式地转换为 BigInt。当我们尝试将 42(常规数字)与 42n(或 BigInt)相加时,它抛出了一个错误,该错误被 try catch 捕获并显示在屏幕上。
<!DOCTYPE html>
<html>
<body>
<h2>Adding BigInt & Regular Number</h2>
<div id="output"></div>
<script>
const regularNumber = 42;
const bigIntValue = BigInt(regularNumber); // Explicit conversion
document.getElementById("output").innerHTML =
`<p>Regular Number: ${regularNumber}</p>`+
`<p>BigInt Value: ${bigIntValue}</p>` +
`<p>Regular Number + BigInt Value results in:</p>`;
try {
const result = regularNumber + bigIntValue;
document.getElementById("output").innerHTML += `Result: ${result}`;
} catch (e) {
document.getElementById("output").innerHTML += `Error: ${e}`;
}
</script>
</body>
</html>

