Friday, December 2, 2011

Pi to any precision ported to Dart


try.dartlang.org/s/q2Ui

Click the link, then click the button in the upper left part of the pane.

It works in Chrome and Firefox, I'm not sure if they have it working in IE yet.

It takes 7 to 10 seconds to do 1000 digits of Pi on my machine with Dart, which is based on javascript.
With Java, it only takes 0.09 seconds, so java is way faster (so far).

Doug

/** Pi
* I found an old C program which
* prints out lots of digits of pi.
* I ported it to java (and now to dart)
* © 2011 Douglas A. Bauman
* Here it is in case you are interested.
* -Doug
*/

class Pi {

static final int MAXPRC = 20000;
StringBuffer bufDigits;
StringBuffer buf;
StringBuffer bufTime;
List<int> p; // = new List<int>(MAXPRC); // byte[]
List<int> t; // = new List<int>(MAXPRC); // byte[]
int q;

Pi(){
}

setQ(int q) {
this.q = q;
bufDigits = new StringBuffer();
bufDigits.add("digits: "+q);
buf = new StringBuffer();
bufTime = new StringBuffer();
}

arctan(int s) {
int n;
t[0] = 1;
div6(s); /* t[] = 1/s */
add5();
n = 1;
do {
mul7(n);
div6(s * s);
div6(n += 2);
if (((n-1) / 2) % 2 == 0) {
add5();
} else {
sub8();
}
} while (!tiszero());
}

add5() {
int j;
for (j = q; j >= 0; j--) {
if (t[j] + p[j] > 9) {
p[j] += t[j] - 10;
if (j>=0) p[j-1] += 1;
} else {
p[j] += t[j];
}
}
}

sub8() {
int j;
for (j = q; j >= 0; j--) {
if (p[j] < t[j]) {
p[j] -= t[j] - 10;
if (j>=0) p[j-1] -= 1;
} else {
p[j] -= t[j];
}
}
}

mul7(int multiplier) {
int b;
int i;
num carry=0;
int digit = 0;
for (i = q; i >= 0; i--) {
b = (t[i] * multiplier + carry);
digit = b % 10;
carry = (b / 10).floor();
t[i] = digit; //(byte)
}
}

/* t[] /= l */
div6(int divisor) {
int i, b;
num quotient, remainder = 0;
for (i = 0; i <= q; i++) {
b = (10 * remainder + t[i]);
quotient = (b / divisor).floor();
remainder = b % divisor;
t[i] = quotient; // (byte)
}
}

div4() {
int i=0, d = 0;
num c=0;
for (; i <= q; i++) {
c = ((10 * d + p[i]) / 4).floor();
d = (10 * d + p[i]) % 4;
p[i] = c; // (byte)
}
}

mul4() {
int i;
num d=0;
num c=0;
for (i = q; i >= 0; i--) {
d = (p[i] * 4 + c) % 10;
c = (p[i] * 4 + c) / 10;
p[i] = d.floor(); // (byte)
}
}

bool tiszero() {
int k;
for (k = 0; k <= q; k++)
if (t[k] != 0)
return(false);
return(true);
}

compute() {
int i;
print(getAppletInfo());
print("..compute..");
if (q > MAXPRC) {
buf.add("Precision too large: "+q+", >MAX: "+MAXPRC);
return;
}

/* compute pi */
p = new List<int>(MAXPRC+1);
t = new List<int>(MAXPRC+1);
for(int ii=0; ii<=q; ii++) {p[ii]=0; t[ii]=0;}

Date startime = new Date.now();
print("..arctan(2)..");
arctan(2);
print("..arctan(3)..");
arctan(3);
print("..mul..");
mul4();

Date endtime = new Date.now();
Duration diff = endtime.difference(startime);

/* print pi */
bufTime.add(""+diff.toString()+
" seconds to compute "+q+" digits of pi");
print(bufDigits.toString());

print("pi = ");
i = 0;
int km = 79;
int f = 1;
do {
for (int k=0; i <= q && k < km; i++, k++) {
buf.add(""+(p[i]==null?'?':p[i]));
if (i==0) buf.add(".");
}
print(buf.toString());
buf = new StringBuffer();
km+= f;
f=0;
} while (i <= q);

print(buf.toString());
print(bufTime.toString());
}

String getAppletInfo() {
return "Pi by Douglas A. Bauman";
}
}
main() {
int q = 1000;
print("calculating Pi for " + q + " digits...");
Pi pi = new Pi();
pi.setQ(q);
pi.compute();

}

No comments:

Post a Comment