插件窝 干货文章 JavaScript如何精确计算圆周率到任意位数?

JavaScript如何精确计算圆周率到任意位数?

BigInt decimal 计算 BigNumber 920    来源:    2025-03-19

在JavaScript中,精确计算圆周率(π)到任意位数是一个复杂的任务,因为JavaScript的浮点数精度有限(通常是64位浮点数,精度约为15-17位小数)。要计算π到更高的精度,通常需要使用专门的算法和库。

以下是几种常见的方法:

1. 使用BigInt和数学公式

JavaScript的BigInt类型可以用来处理大整数,结合一些数学公式(如BBP公式)可以计算π的任意位数。BBP公式(Bailey-Borwein-Plouffe公式)是一种可以计算π的任意位数的公式。

function calculatePi(digits) {
    const scale = BigInt(10) ** BigInt(digits + 20); // 增加20位以避免舍入误差
    let pi = BigInt(0);
    for (let k = 0; k <= digits; k++) {
        pi += (scale * BigInt(4)) / (BigInt(8) * BigInt(k) + BigInt(1)) -
              (scale * BigInt(2)) / (BigInt(8) * BigInt(k) + BigInt(4)) -
              (scale * BigInt(1)) / (BigInt(8) * BigInt(k) + BigInt(5)) -
              (scale * BigInt(1)) / (BigInt(8) * BigInt(k) + BigInt(6));
    }
    return pi.toString().slice(0, digits + 2); // 返回结果,去掉多余的位数
}

console.log(calculatePi(100)); // 计算π的前100位

2. 使用第三方库

为了简化计算过程,可以使用一些专门用于高精度计算的JavaScript库,如big.jsdecimal.jsmath.js。这些库提供了高精度的数学运算功能。

例如,使用decimal.js

const Decimal = require('decimal.js');

function calculatePi(digits) {
    Decimal.set({ precision: digits + 2 });
    let pi = new Decimal(0);
    for (let k = 0; k <= digits; k++) {
        pi = pi.plus(new Decimal(4).dividedBy(new Decimal(8 * k + 1))
              .minus(new Decimal(2).dividedBy(new Decimal(8 * k + 4))
              .minus(new Decimal(1).dividedBy(new Decimal(8 * k + 5))
              .minus(new Decimal(1).dividedBy(new Decimal(8 * k + 6)));
    }
    return pi.toPrecision(digits + 2);
}

console.log(calculatePi(100)); // 计算π的前100位

3. 使用Chudnovsky算法

Chudnovsky算法是一种非常高效的π计算算法,适合计算π的极高精度值。

function calculatePiChudnovsky(digits) {
    const BigNumber = require('bignumber.js');
    BigNumber.config({ DECIMAL_PLACES: digits + 2 });

    let C = new BigNumber(426880).times(new BigNumber(10005).sqrt());
    let sum = new BigNumber(0);
    let M = new BigNumber(1);
    let L = new BigNumber(13591409);
    let X = new BigNumber(1);
    let K = new BigNumber(6);

    for (let k = 0; k <= digits; k++) {
        let term = M.times(L).dividedBy(X);
        sum = sum.plus(term);
        M = M.times(K.pow(3).minus(16 * K)).dividedBy((k + 1).pow(3));
        L = L.plus(545140134);
        X = X.times(-262537412640768000);
        K = K.plus(12);
    }

    return C.dividedBy(sum).toPrecision(digits + 2);
}

console.log(calculatePiChudnovsky(100)); // 计算π的前100位

总结

  • BigInt和数学公式:适合简单的实现,但需要手动处理精度问题。
  • 第三方库:如decimal.js,提供了高精度的数学运算,简化了计算过程。
  • Chudnovsky算法:适合计算π的极高精度值,但实现较为复杂。

根据你的需求选择合适的方案。如果你需要计算π的极高精度值,建议使用Chudnovsky算法或第三方库。