2015-06-10 79 views
-5

有什麼方法可以在Javascript中計算pi?我知道那裏可以使用Math.PI找到餡餅這樣的:Javascript:PI(π)計算器

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

但是這是不準確的。我想要的是能夠計算出它的數量,只要你想要的數字,不像pie = 3.141592...。但仍然,我想要的不只是有更多的數字,但儘可能多的(如有千位數,但我需要)。

+5

當然! Javascript是一個圖靈完整的語言 – Paulpro

+0

你的問題的答案是肯定的。我非常肯定,如果你爲Google做*如何做,你會發現足夠的資源。 –

+1

您是否已經知道您將使用哪種數據類型來存儲計算結果? – zerkms

回答

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

@蔡海陽工作的方式是你完成一些高一些的數學和編程,有一些關於JS和浮點錯誤的知識,你可以一步一步地讀那些腳本,獲得一些線索和做筆記:) –

+0

沒有太多的學習, ,我認爲,請參閱它在數組中執行以基數10 11爲單位的多個精度算術,其長度超過了保存所需的十進制數字所需的時間。我認爲這會給出錯誤留下一個公平的餘地,但我不知道有多少可以確定。我不知道它有多快。 – PJTraill

0

您可以使用此爲您的目的

Math.PI.toFixed(N)

其中n是要顯示的小數位數。

它顯示pi的四捨五入值。它可以被認爲是相當正確的小數點後15位。

+1

返回的數字不是PI號碼。 –

+1

這實際上並沒有返回pi,而是pi的最接近逼近的實際數字,是一個從2到n的小數位數。 –

-3

使用toFixed()這樣的方法。在toFixed內部,您可以確定小數點後顯示的位數。

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

This returns'3.14159265358979311600' – chris97ong

+4

As @ chris97ong said,that number is not PI。 –

+1

@ RokoC.Buljan:誰在乎 - 至少它的數字是位數!也許π確實是有理性的(或者至少是代數的)。 – PJTraill

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; 
} 
+0

這種計算的精度是多少?我的意思是它在什麼時候關閉? –

+0

由於它使用蒙特卡洛模擬,因此可能無法產生良好的結果,特別是對於少數試驗。然而,隨着試驗次數的增加,良好結果的可能性會增加。所以,精度是非確定性的。 – andand

+0

由於浮點數的語義,如果不使用BigDecimal庫,不可能比'Math.PI'更精確地表示pi。 –