[查看演示] 源码如下 ---------------------------------------------------------- <HTML>
<HEAD>
<META NAME="keywords" CONTENT="Pi, machin, javascipt, numerical methods, multiple precision, series">
<TITLE>PI in JavaScript-www.51windows.Net</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
//
// arctangent series for Pi a la mode by Bohr
//
var vectorsize = 53; // number of elements in each of four arrays
var nCells = 52; // number of array elements displayed
// constant
var BASE = 10000.0; // The number base
var TENTHOUSANDTH = 0.0001; // avoids floating point division
var SQ_239E4 = 571210000.0; // = BASE x 239 squared
var SQ_5E4 = 250000.0; // = BASE x 5 squared
var REPAIR = 0.000005; // roundoff correction
var RECIPR_25 = 0.04; // the reciprocal of 25 is 0.04
var RECIPR_239= 1.0 / 57121; // reciprocal of 239 squared
// arrays
var term5 = null; // = (1/5)^(2n+1), integer array
var term239 = null; // = (1/239)^(2n+1), integer array
var sum = null; // = 16term5-4term239, integer array
var series = null; // = PI
// floating or integer
var TwoNplus1 = 1.0; // 2n+1 = 1,3,5,7,...
var Basex2n_1 = BASE; // = 10000*(2n+1)
var Currdigit = 1; // index of the series[] element being printed
var sgn = 1; // = (-1)^n; takes the values -1 and 1
// strings
var IntroString = " Pi = 3.";
function MakeArray(n) {
this.length = n;
for (var i = 1; i <= n; i++) {
this[i] = 0;
}
return this;
}
function PiSetup() {
term5 = new MakeArray(vectorsize);
term239 = new MakeArray(vectorsize);
sum = new MakeArray(vectorsize);
series = new MakeArray(vectorsize);
term5[1] = 5;
term239[1] = 239;
}
function DivideTerms() {
var total5 = term5[1];
var total239 = term239[1];
// Divide the terms by 25 or 57121
for (var i = Currdigit; i <= nCells + 2; i++) {
term5[i] = Math.floor( RECIPR_25 * total5 + REPAIR );
total5 = BASE * total5 - SQ_5E4 * term5[i] + term5[i+1];
term239[i] = Math.floor( total239 * RECIPR_239 + REPAIR );
total239 = BASE * total239 - SQ_239E4 * term239[i] + term239[i+1];
}
}
function SubtractTerms() {
var carry = 0;
var total = 0;
for (var i = nCells + 1; i > Currdigit; i--) {
total = 16.0 * term5[i] - 4.0 * term239[i] + carry + 60000.0;
carry = Math.floor( total * TENTHOUSANDTH + REPAIR ) - 6.0;
sum[i] = Math.floor( total - BASE * carry - 60000.0 );
}
}
function DivideSum() {
var total = sum[1];
var reciprocal = 1.0 / TwoNplus1;
for( var i = Currdigit; i <= nCells + 2; i++) {
sum[i] = Math.floor( total * reciprocal + REPAIR );
total = BASE * total - Basex2n_1 * sum[i] + sum[i+1];
}
}
function AddShowDigits(nchars,lwidth) {
var i = 0;
var total = 0;
var carry = 0;
var ccount = nchars / 4;
var strg = "x";
var old1 = series[Currdigit+1];
var old2 = series[Currdigit+2];
// Add the sum to the series
for (i = nCells + 1; i >= Currdigit; i--) {
total = series[i] + sgn * sum[i] + carry + 30000.0;
carry = Math.floor( total * TENTHOUSANDTH + REPAIR ) - 3.0;
series[i] = Math.floor( total - BASE * carry - 30000.0 );
}
// if stable, display digits
if((old1==series[Currdigit+1]) && (old2==series[Currdigit+2])) {
Currdigit++;
ccount++;
if (ccount > lwidth / 4) {
document.write("<BR>")
ccount = 1;
}
strg = (BASE + series[Currdigit]) + " ";
document.write(strg.substring(1,5))
}
return (4 * ccount);
}
function Crunch(fontname,fontsize) {
var linelength = IntroString.length;
var time0 = new Date();
var linewidth = 4 * Math.floor(50.0 / fontsize)
window.status = ".. calculating "+(4 * nCells)+" digits, please wait .."
document.write('<UL><FONT SIZE=' + fontsize + ' FACE="' + fontname + '">')
document.write(IntroString)
while (Currdigit < nCells) {
DivideTerms()
SubtractTerms()
DivideSum()
linelength = AddShowDigits(linelength, linewidth)
// Set up the next value of n
TwoNplus1 += 2.0;
Basex2n_1 = BASE * TwoNplus1;
sgn = 0 - sgn;
}
var time1 = new Date();
var elapsed = time1.getTime() - time0.getTime();
document.write("</FONT>")
document.write("<BR><BR><B>" + (4 * nCells) + " digits calculated in ")
document.write((Math.floor(elapsed)/1000.0) + " seconds.</B>")
document.write("</UL>")
}
PiSetup()
// -->
</SCRIPT>
</HEAD>
<BODY TEXT="#000000" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000" BACKGROUND="litepie3.jpg">
<br>
<CENTER>
<B><FONT SIZE=+1>Machin's Arctangent Series for Pi in JavaScript</FONT></B>
<A HREF="../mathindex.html">
<IMG SRC="p_btn3.jpg" BORDER="0" HSPACE=14 HEIGHT=40 WIDTH=110 ALIGN=ABSCENTER></A>
</CENTER>
<hr>
<SCRIPT LANGUAGE="JavaScript">
<!--
Crunch("Courier New", 4)
// -->
</SCRIPT>
<hr>
<CENTER>Click "View: Page Source" to see the Javascript source code</CENTER>
<P><B>In 1706 John Machin</B> discovered the trigonometric identity</P>
<PRE> PI = 16 arctan(1/5) - 4 arctan(1/239)</PRE>
and used it to calculate the first one hundred digits of Pi. He combined
his formula with the Taylor series expansion for the inverse tangent of
x. (Brook Taylor was Machin's contemporary in Cambridge.) The arctangent
series is
<PRE> 3 5 7 n 2n+1
arctan(x) = x - x /3 + x /5 - x /7 +...+ (-1) x /(2n+1) +..</PRE>
Machin's formula remained the primary tool of Pi-hunters for centuries. As
late as 1973, Guilloud and Bouyer used a variation of it to compute one
million digits of Pi on a CDC 7600.
<P>This program uses arrays of multiple precision digits for the two series
terms, for their sum, and for the series. Each 'digit' is a modulo 10000
integer. The number base is 10,000.
</P>
<P>In the end, John Machin was never cured.
</P>
<HR SIZE=3 WIDTH="100%">
<B><FONT SIZE=-1>AUTHOR:</FONT></B> <TT> John Bohr </TT>
<A HREF="mailto:jnbohr@netscape.net">email me</A>
<BR><TT>Last updated: 1 October 1998</TT>
<BR>
</BODY>
</HTML>
<div style="position: absolute; top: 10; right: 10; width: 148; height: 18;cursor:hand">
<input type="button" name="Button" value="查看源代码" onClick= 'window.location = "view-source:" + window.location.href'></div> |