Javascript:PI(π)计算器

时间:2015-06-10 04:40:02

标签: javascript math pi

有没有办法在Javascript中计算pi?我知道你可以使用Math.PI找到这样的馅饼:

var pie = Math.PI;
alert(pie); // output "3.141592653589793"

但这不准确。我想要的是能够计算它,拥有任意数量的数字,而不是像pie = 3.141592...那样的数字。但是,我想要的不仅仅是拥有更多数字,而是尽可能多(比如拥有一千个数字,但我需要更多)。

6 个答案:

答案 0 :(得分:2)

我在this website上找到了这段代码:

<html>
  <head>
    <title>Pi</title>
    <script type="text/javascript">
      mess = "";
      Base = Math.pow(10, 11);
      cellSize = Math.floor(Math.log(Base) / Math.LN10);
      a = Number.MAX_VALUE;
      MaxDiv = Math.floor(Math.sqrt(a));
      function makeArray(n, aX, Integer) {
        var i = 0;
        for (i = 1; i < n; i++) aX[i] = null;
        aX[0] = Integer
      }
      function isEmpty(aX) {
        var empty = true
        for (i = 0; i < aX.length; i++) if (aX[i]) {
          empty = false;
          break
        }
        return empty
      }
      function Add(n, aX, aY) {
        carry = 0
        for (i = n - 1; i >= 0; i--) {
          aX[i] += Number(aY[i]) + Number(carry);
          if (aX[i] < Base) carry = 0;
          else {
            carry = 1;
            aX[i] = Number(aX[i]) - Number(Base)
          }
        }
      }
      function Sub(n, aX, aY) {
        for (i = n - 1; i >= 0; i--) {
          aX[i] -= aY[i];
          if (aX[i] < 0) {
            if (i > 0) {
              aX[i] += Base;
              aX[i - 1]--
            }
          }
        }
      }
      function Mul(n, aX, iMult) {
        carry = 0;
        for (i = n - 1; i >= 0; i--) {
          prod = (aX[i]) * iMult;
          prod += carry;
          if (prod >= Base) {
            carry = Math.floor(prod / Base);
            prod -= (carry * Base)
          } else carry = 0;
          aX[i] = prod
        }
      }
      function Div(n, aX, iDiv, aY) {
        carry = 0;
        for (i = 0; i < n; i++) {
          currVal = Number(aX[i]) + Number(carry * Base);
          theDiv = Math.floor(currVal / iDiv);
          carry = currVal - theDiv * iDiv;
          aY[i] = theDiv
        }
      }
      function arctan(iAng, n, aX) {
        iAng_squared = iAng * iAng;
        k = 3;
        sign = 0;
        makeArray(n, aX, 0);
        makeArray(n, aAngle, 1);
        Div(n, aAngle, iAng, aAngle);
        Add(n, aX, aAngle);
        while (!isEmpty(aAngle)) {
          Div(n, aAngle, iAng_squared, aAngle);
          Div(n, aAngle, k, aDivK);
          if (sign) Add(n, aX, aDivK);
          else Sub(n, aX, aDivK);
          k += 2;
          sign = 1 - sign
        }
        mess += "aArctan=" + aArctan + "<br>"
      }
      function calcPI(numDec) {
        var ans = "";
        t1 = new Date();
        numDec = Number(numDec) + 5;
        iAng = new Array(10);
        coeff = new Array(10);
        arrayLength = Math.ceil(1 + numDec / cellSize);
        aPI = new Array(arrayLength);
        aArctan = new Array(arrayLength);
        aAngle = new Array(arrayLength);
        aDivK = new Array(arrayLength);
        coeff[0] = 4;
        coeff[1] = -1;
        coeff[2] = 0;
        iAng[0] = 5;
        iAng[1] = 239;
        iAng[2] = 0;
        makeArray(arrayLength, aPI, 0);
        makeArray(arrayLength, aAngle, 0);
        makeArray(arrayLength, aDivK, 0);
        for (var i = 0; coeff[i] != 0; i++) {
          arctan(iAng[i], arrayLength, aArctan);
          Mul(arrayLength, aArctan, Math.abs(coeff[i]));
          if (coeff[i] > 0) Add(arrayLength, aPI, aArctan);
          else Sub(arrayLength, aPI, aArctan)
        }
        Mul(arrayLength, aPI, 4);
        sPI = "";
        tempPI = "";
        for (i = 0; i < aPI.length; i++) {
          aPI[i] = String(aPI[i]);
          if (aPI[i].length < cellSize && i != 0) {
            while (aPI[i].length < cellSize) aPI[i] = "0" + aPI[i]
          }
          tempPI += aPI[i]
        }
        for (i = 0; i <= numDec; i++) {
          if (i == 0) sPI += tempPI.charAt(i) + ".<br>";
          else {
            if (document.getElementById("cbCount").checked) addcount = " (" + (i) + ")";
            else addcount = "";
            if (document.getElementById("cbSpace").checked) thespace = " ";
            else thespace = "";
            if ((i) % 50 == 0 && i != 0) sPI += tempPI.charAt(i) + addcount + "<br>";
            else if (i % 5 == 0) sPI += tempPI.charAt(i) + thespace;
            else sPI += tempPI.charAt(i)
          }
        }
        ans += ("PI (" + numDec + ")=" + sPI + "<br>");
        ans += ("Win PI=<br>3.1415926535897932384626433832795<br>");
        t2 = new Date();
        timeTaken = (t2.getTime() - t1.getTime()) / 1000;
        ans += "It took: " + timeTaken + " seconds";
        var myDiv = document.getElementById("d1");
        myDiv.innerHTML = ans
      }
    </script>
  </head>
  <body>
    <h1>
      Pi Machin
    </h1>
    <form name="" id="" method="post" action="" enctype="text/plain" onsubmit="calcPI(this.t1.value);return false;">
      Number of Digits:<br>
      <input type="text" name="t1" id="t1" value="100" size="25" maxlength="25">
      <br>Add Count:
      <input type="checkbox" name="cbCount" id="cbCount" value="" checked="checked">
      <br>Add Spaces:
      <input type="checkbox" name="cbSpace" id="cbSpace" value="" checked="checked">
      <br>
      <input type="button" value="Calculate Pi" onclick="calcPI(this.form.t1.value)">
    </form>
    <div id="d1">0</div>
  </body>
</html>

答案 1 :(得分:2)

您可以通过使用蒙特卡罗模拟来近似π的值。在[-1,1]范围内生成随机X和Y然后,似然(X,Y)在以原点为中心的单位圆中是π/ 4。更多样本可以更好地估计其价值。然后,您可以通过比较单位圆中的样本与样本总数的比率并乘以4来估算π。

this.pi = function(count) {
    var inside = 0;

    for (var i = 0; i < count; i++) {
        var x = random()*2-1;
        var y = random()*2-1;
        if ((x*x + y*y) < 1) {
            inside++
        }
    }

    return 4.0 * inside / count;
}

答案 2 :(得分:1)

您可以将此用于您的目的

  

Math.PI.toFixed(n)的

其中n是您希望显示的小数位数。

显示pi的舍入值。它可以被认为是相当正确的,最多15位小数。

答案 3 :(得分:1)

以下是使用 无限系列

的实现方式
function calculatePI(iterations = 10000){
    let pi = 0;
    let iterator = sequence();

    for(let i = 0; i < iterations; i++){
        pi += 4 /  iterator.next().value;
        pi -= 4 / iterator.next().value;
    }

    function* sequence() {
      let i = 1;
      while(true){
        yield i;
        i += 2;
      }
    }

    return pi;
}

答案 4 :(得分:1)

这是Jeremy Gibbons在Unbounded Spigot Algorithms for the Digits of Pi(2004年)第6章中描述的流算法的实现:

function * generateDigitsOfPi() {
    let q = 1n;
    let r = 180n;
    let t = 60n;
    let i = 2n;
    while (true) {
        let digit = ((i * 27n - 12n) * q + r * 5n) / (t * 5n);
        yield Number(digit);
        let u = i * 3n;
        u = (u + 1n) * 3n * (u + 2n);
        r = u * 10n * (q * (i * 5n - 2n) + r - t * digit);
        q *= 10n * i * (i++ * 2n - 1n);
        t *= u;
    }
}

// Demo
let iter = generateDigitsOfPi();

let output = document.querySelector("div");
(function displayTenNextDigits() {
    let digits = "";
    for (let i = 0; i < 10; i++) digits += iter.next().value;
    output.insertAdjacentHTML("beforeend", digits);
    scrollTo(0, document.body.scrollHeight);
    requestAnimationFrame(displayTenNextDigits);
})();
div { word-wrap:break-word; font-family: monospace }
<div></div>

答案 5 :(得分:-3)

像这样使用toFixed()方法。在toFixed里面你可以修复小数点后显示的位数。

var n=22/7;
console.log(n.toFixed(20))