Friday, June 6, 2014

Updated for 2014: Pi to any precision ported to Dart





It used to take 7 to 10 seconds to do 1000 digits of Pi on my machine with the original version of Dart, which is was based on javascript.

The new version of dart (c. 2014) now calcuates 3500 digits of Pi in 1.88 seconds. My Java version is only slightly faster, 3500 digits of PI in 1.39 seconds.

Douglas Bauman
/** 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 - © 2014 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.write("digits: "+q.toString());
        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.write("Precision too large: "+q.toString()+", >MAX: "+MAXPRC.toString());
            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;}

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

        DateTime endtime = new DateTime.now();
        Duration diff = endtime.difference(startime);
 
        /* print pi */
        bufTime.write(""+diff.toString()+
          " seconds to compute "+q.toString()+" 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.write(""+(p[i]==null?"?":p[i].toString()));
            if (i==0) buf.write(".");
          }
          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 = 3500;
    print("calculating Pi for " + q.toString() + " digits...");
    Pi pi = new Pi();
    pi.setQ(q);
    pi.compute();

}

output:
calculating Pi for 3500 digits...
Pi by Douglas A. Bauman
..compute..
..arctan(2)..
..arctan(3)..
..mul..
digits: 3500
pi = 
3.141592653589793238462643383279502884197169399375105820974944592307816406286208
99862803482534211706798214808651328230664709384460955058223172535940812848111745
02841027019385211055596446229489549303819644288109756659334461284756482337867831
65271201909145648566923460348610454326648213393607260249141273724587006606315588
17488152092096282925409171536436789259036001133053054882046652138414695194151160
94330572703657595919530921861173819326117931051185480744623799627495673518857527
24891227938183011949129833673362440656643086021394946395224737190702179860943702
77053921717629317675238467481846766940513200056812714526356082778577134275778960
91736371787214684409012249534301465495853710507922796892589235420199561121290219
60864034418159813629774771309960518707211349999998372978049951059731732816096318
59502445945534690830264252230825334468503526193118817101000313783875288658753320
83814206171776691473035982534904287554687311595628638823537875937519577818577805
32171226806613001927876611195909216420198938095257201065485863278865936153381827
96823030195203530185296899577362259941389124972177528347913151557485724245415069
59508295331168617278558890750983817546374649393192550604009277016711390098488240
12858361603563707660104710181942955596198946767837449448255379774726847104047534
64620804668425906949129331367702898915210475216205696602405803815019351125338243
00355876402474964732639141992726042699227967823547816360093417216412199245863150
30286182974555706749838505494588586926995690927210797509302955321165344987202755
96023648066549911988183479775356636980742654252786255181841757467289097777279380
00816470600161452491921732172147723501414419735685481613611573525521334757418494
68438523323907394143334547762416862518983569485562099219222184272550254256887671
79049460165346680498862723279178608578438382796797668145410095388378636095068006
42251252051173929848960841284886269456042419652850222106611863067442786220391949
45047123713786960956364371917287467764657573962413890865832645995813390478027590
09946576407895126946839835259570982582262052248940772671947826848260147699090264
01363944374553050682034962524517493996514314298091906592509372216964615157098583
87410597885959772975498930161753928468138268683868942774155991855925245953959431
04997252468084598727364469584865383673622262609912460805124388439045124413654976
27807977156914359977001296160894416948685558484063534220722258284886481584560285
06016842739452267467678895252138522549954666727823986456596116354886230577456498
03559363456817432411251507606947945109659609402522887971089314566913686722874894
05601015033086179286809208747609178249385890097149096759852613655497818931297848
21682998948722658804857564014270477555132379641451523746234364542858444795265867
82105114135473573952311342716610213596953623144295248493718711014576540359027993
44037420073105785390621983874478084784896833214457138687519435064302184531910484
81005370614680674919278191197939952061419663428754440643745123718192179998391015
91956181467514269123974894090718649423196156794520809514655022523160388193014209
37621378559566389377870830390697920773467221825625996615014215030680384477345492
02605414665925201497442850732518666002132434088190710486331734649651453905796268
56100550810665879699816357473638405257145910289706414011097120628043903975951567
71577004203378699360072305587631763594218731251471205329281918261861258673215791
98414848829164470609575270695722091756711672291098169091528017350671274858322287
18352093539657251210835791513698820914442100675103346711031336

0:00:01.846000 seconds to compute 3500 digits of pi

No comments:

Post a Comment