![]() |
Forum Index : Microcontroller and PC projects : Blueberry Pi
Author | Message | ||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
We had a good crop of blueberries this year so I had to make a Pi. Well, actually, there was a program to calculate Pi to any number of digits on another forum so I had to port it over to MMBasic. The program uses integers throughout so MMBasic can handle it OK. Various results: Reference pi = 3.1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196 4428810975 6659334461 2847564823 3786783165 2712019091 4564856692 3460348610 4543266482 1339360726 0249141273 7245870066 0631558817 4881520920 9628292540 9171536436 7892590360 0113305305 4882046652 1384146951 9415116094 3305727036 5759591953 0921861173 8193261179 3105118548 0744623799 6274956735 1885752724 8912279381 8301194912 9833673362 4406566430 8602139494 6395224737 1907021798 6094370277 0539217176 2931767523 8467481 DOS how many digits? 500 pi = 3.1415926535 8979323846 2643383279 5028841971 6939937510 50 5820974944 5923078164 0628620899 8628034825 3421170679 100 8214808651 3282306647 0938446095 5058223172 5359408128 150 4811174502 8410270193 8521105559 6446229489 5493038196 200 4428810975 6659334461 2847564823 3786783165 2712019091 250 4564856692 3460348610 4543266482 1339360726 0249141273 300 7245870066 0631558817 4881520920 9628292540 9171536436 350 7892590360 0113305305 4882046652 1384146951 9415116094 400 3305727036 5759591953 0921861173 8193261179 3105118548 450 0744623799 6274956735 1885752724 8912279381 8301194912 500 total computation time: 62 mS Armite L4 how many digits? 500 pi = 3.1415926581 8979323846 2643383279 5028841971 6939937510 50 5820974944 5923078164 0628620899 8628034825 3421170679 100 8214808651 3282306647 0938446095 5058223172 5359408128 150 4811174502 8410270193 8521105559 6446229489 5493038196 200 4428810975 6659334461 2847564823 3786783165 2712019091 250 4564856692 3460348610 4543266482 1339360726 0249141273 300 7245870066 0631558817 4881520920 9628292540 9171536436 350 7892590360 0113305305 4882046652 1384146951 9415116094 400 3305727036 5759591953 0921861173 8193261179 3105118548 450 0744623799 6274956735 1885752724 8912279381 8301194912 500 total computation time: 12931 mS Explore64 how many digits? 500 pi = 3.1415926535 8979323846 2643383279 5028841971 6939937510 50 5820974944 5923078164 0628620899 8628034825 3421170679 100 8214808651 3282306647 0938446095 5058223172 5359408128 150 4811174502 8410270193 8521105559 6446229489 5493038196 200 4428810975 6659334461 2847564823 3786783165 2712019091 250 4564856692 3460348610 4543266482 1339360726 0249141273 300 7245870066 0631558817 4881520920 9628292540 9171536436 350 7892590360 0113305305 4882046652 1384146951 9415116094 400 3305727036 5759591953 0921861173 8193261179 3105118548 450 0744623799 6274956735 1885752724 8912279381 8301194912 500 total computation time: 5394 mS Armite H7 how many digits? 500 pi = 3.1415926535 8979323846 2643383279 5028841971 6939937510 50 5820974944 5923078164 0628620899 8628034825 3421170679 100 8214808651 3282306647 0938446095 5058223172 5359408128 150 4811174502 8410270193 8521105559 6446229489 5493038196 200 4428810975 6659334461 2847564823 3786783165 2712019091 250 4564856692 3460348610 4543266482 1339360726 0249141273 300 7245870066 0631558817 4881520920 9628292540 9171536436 350 7892590360 0113305305 4882046652 1384146951 9415116094 400 3305727036 5759591953 0921861173 8193261179 3105118548 450 0744623799 6274956735 1885752724 8912279381 8301194912 500 total computation time: 1233 mS PureBasic how many digits 500 pi = 3.1415926535 8979323846 2643383279 5028841971 6939937510 50 5820974944 5923078164 0628620899 8628034825 3421170679 100 8214808651 3282306647 0938446095 5058223172 5359408128 150 4811174502 8410270193 8521105559 6446229489 5493038196 200 4428810975 6659334461 2847564823 3786783165 2712019091 250 4564856692 3460348610 4543266482 1339360726 0249141273 300 7245870066 0631558817 4881520920 9628292540 9171536436 350 7892590360 0113305305 4882046652 1384146951 9415116094 400 3305727036 5759591953 0921861173 8193261179 3105118548 450 0744623799 6274956735 1885752724 8912279381 8301194912 500 total computation time: 5 mS going to 2000 digits on the H7 7392984896 0841284886 2694560424 1965285022 2106611863 1900 0674427862 2039194945 0471237137 8696095636 4371917287 1950 4677646575 7396241389 0865832645 9958133904 7802759009 2000 total computation time: 17495 mS The code: ' ported by TassyJim from a post on PureBasic forum by Jeff88 ' his comments follow ' ';Many years ago when I used Quickbasic, I came across a program to calc pi. Of course this has no practical ';purpose, but just to fight winter boredom I modified the program (see comments included below) to run ';under Purebasic, now can use 10 digits per word instead of 4. Also added a bit of assembly to avoid calculating ';the remainder, this only makes a slight difference since most of time is taken by dividing. ';Using threads sped up by a factor of 3. Note calc atan(1/5) takes about twice as long as atan(1/239). ';Programmed by Jeff Wyatt, Highlands Ranch, Colorado (1/2019). ' ';On my Athelon II X4 635 the program can calculate 100,000 digits in about 8 secs with debugging off. ' '; >>>>>>>>>>>>>>>>>>>>>>>COMPILE With THREAD SAFE BOX CHECKED<<<<<<<<<<<<<<<<<<<<<<<<<<<< ' ';Based upon Machin's (1706) formula: pi/4=arctan(1)=4*arctan(1/5)-arctan(1/239), he did 100 digits by hand ';which would take about 8 usec with this program. Time is prop. to digits^2 so need to use another method ';for very large number of digits. Good way to test your computer's integer arithmatic. ';See https://www.angio.net/pi/ for further info and searchable listing of pi. ';I used it to check that my program worked correctly for the first 2,000,000 digits. ' ';Previous comments from authors 20 years ago ' ';Program To calculate pi, version 4.8 ';A major rewrite of version 4.2, this uses only two arrays instead of ';three, and includes a host of speedups based on a similar C program. ';A sampler: all the carries are reserved until the end, the divide and ';add routines are combined, two terms are added at a time, and the number ';of function calls is minimized. It's a big change for a small gain, since ';the compiled version requires 28.6 seconds for 5000 digits on my 486 66 MHz ';computer, a 10 gain over version 4.2; like before, it's capable of about ';150,000 digits of pi. '; ';This program has come a long way from version 1.0; thanks are due to ';Larry Shultis, Randall Williams, Bob Farrington and Adrian Umpleby. ';One final note for speed freaks: this program will run about 6 times faster ';if written in C using an optimizing compiler. Likewise, if you can figure ';out a way to do integer division and use both the quotient and remainder, ';this program can easily be sped up by 25. -jasonp@isr.umd.edu option explicit dim integer words, big, Digits, DigitsperWord, x, i, quotient dim integer ctime, stime DigitsperWord=10 big=1 For i=1 To DigitsperWord '1 followed by 10 zeros, note if you use 14 digits/word big=big*10 'arctan(1/5) will overflow about digit 64,760 Next 'when 1.4*digits*big~denom*big >9e18 input "how many digits? ",Digits words = Digits / DigitsperWord+2 Dim integer sum(words + 2),sum1(words+2),sum2(words+2) stime = timer '--------------- -4*atan(1/239) x = atan239() '------------ 16*atan(1/5) x = atan51() x = atan52() sum1(2)=sum1(2)-big/5 For x=2 To words sum(x)=sum(x)+sum1(x)+sum2(x) Next For x = words To 2 Step -1 'finish up If sum(x) < 0 then 'release borrows quotient = sum(x) \ big sum(x) = sum(x) - (quotient - 1) * big sum(x - 1) = sum(x - 1) + quotient - 1 EndIf If sum(x) >= big then 'and carries quotient = sum(x) \ big sum(x) = sum(x) - quotient * big sum(x - 1) = sum(x - 1) + quotient EndIf Next ctime = timer - stime x = PrintOut() End function atan239() 'arctan(x) = x-x^3/3+x^5/5-x^7 .... local integer remainder, remainder1, remainder2, dividend, denom, temp, firstword, x local integer term(words +2), lastword remainder=4 For x = 2 To words dividend = remainder * big 'crunch out 1st term term(x) = dividend \ 239 remainder = dividend - term(x) * 239 sum2(x) = sum2(x) - term(x) 'subtract as we want -atan(1/239) Next x denom=3:firstword=2 do 'do two more terms, add first, subtract second remainder1=0 remainder2=0 For x = firstword To words temp = term(x) dividend = remainder1 * big + temp temp = dividend \ 57121 remainder1 = dividend - temp * 57121 term(x) = temp dividend = remainder2 * big + temp temp = dividend \ denom remainder2 = dividend - temp * denom sum2(x) = sum2(x) + temp Next If term(firstword) = 0 then firstword = firstword + 1 EndIf denom = denom + 2 remainder1 = 0: remainder2 = 0 For x = firstword To words temp = term(x) dividend = remainder1 * big + temp temp = dividend \ 57121 remainder1 = dividend - temp * 57121 term(x) = temp dividend = remainder2 * big + temp temp = dividend \ denom remainder2 = dividend - temp * denom sum2(x) = sum2(x) - temp Next x If term(firstword) = 0 then firstword = firstword + 1 EndIf denom = denom + 2 loop Until firstword >=words End function '------------------------------------------------------------------- function atan51() ' atan(1/5) one half of calc terms 1/5, 1/9, 1/13 ...... local integer remainder, remainder1, remainder2, dividend, denom, temp, firstword, x local integer term(words +2), lastword denom = 5: firstword = 1: lastword =3 sum(1) = 3: term(1) = 3: sum(2) = big/5: term(2) = sum(2) do remainder1=0 remainder2=0 For x = firstword To lastword + 1 temp = term(x) dividend = remainder1 * big + temp temp = dividend \ 625 ' 625 = 5^4 remainder1 = dividend - temp * 625 term(x) = temp dividend = remainder2 * big + temp temp = dividend \ denom remainder2 = dividend - temp * denom sum(x) = sum(x) + temp Next For x = lastword + 2 To words dividend = remainder2 * big temp = dividend \ denom remainder2 = dividend - temp * denom sum(x) = sum(x) + temp Next If term(lastword + 1) > 0 And lastword < words then lastword = lastword + 1 EndIf If term(firstword) = 0 then firstword = firstword + 1 EndIf denom = denom + 4 loop Until firstword >= words End function function atan52() ' atan(1/5) other half of calc terms 1/3, 1/7, 1/11 .... local integer remainder, remainder1, remainder2, dividend, denom, temp, firstword, x local integer term(words +2), lastword denom = 3: firstword = 1: lastword =3 sum1(1) = 3: term(1) = 3: sum1(2) = big/5: term(2) = sum1(2) remainder1=0 remainder2=0 For x = firstword To lastword + 1 'term 1/3 temp = term(x) dividend = remainder1 * big + temp temp = dividend \ 25 remainder1 = dividend - temp * 25 term(x) = temp dividend = remainder2 * big + temp temp = dividend \ denom remainder2 = dividend - temp * denom sum1(x) = sum1(x) - temp Next For x = lastword + 2 To words dividend = remainder2 * big temp = dividend \ denom remainder2 = dividend - temp * denom sum1(x) = sum1(x) - temp Next If term(lastword + 1) > 0 And lastword < words then lastword = lastword + 1 EndIf If term(firstword) = 0 then firstword = firstword + 1 EndIf denom = denom + 4 do 'do the rest remainder1 = 0: remainder2 = 0 For x = firstword To lastword + 1 temp = term(x) dividend = remainder1 * big + temp temp = dividend \ 625 remainder1 = dividend - temp * 625 term(x) = temp dividend = remainder2 * big + temp 'eventually this will overflow >9e18 temp = dividend \ denom remainder2 = dividend - temp * denom sum1(x) = sum1(x) - temp Next x For x = lastword + 2 To words dividend = remainder2 * big temp = dividend \ denom remainder2 = dividend - temp * denom sum1(x) = sum1(x) -temp Next x If term(lastword + 1) > 0 And lastword < words then lastword = lastword + 1 EndIf If term(firstword) = 0 then firstword = firstword + 1 EndIf denom = denom + 4 loop Until firstword >= words End function function PrintOut() local p$, i as integer, j as integer Print "" p$="pi = 3." i=2 do For j=i To i+4 If j>words then p$=p$+Space$(11) Else p$=p$+Str$(sum(j),10,0,"0")+" " EndIf Next p$=p$+Str$(10*i+30,7) Print p$ p$=" " i=i+5 loop Until i>=words Print "" Print " total computation time: "+Str$(ctime)+" mS" End function We really did have a good crop of Blueberries. Jim VK7JH MMedit |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
This is pretty cool. Thanks for the comparison work too. I just sing this song in my head when I need to get to about 100 digits. Not as fast as an L4 though... |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10315 |
Here are my figures. It is interesting that the various benchmarks are now showing quite different performance orders for the various platforms depending on the mix of string, FP, and integer calculation Pi-3B 592 mS Armmite H7 1231 mS MMX @ 252MHz 1660 mS MMX @ 200MHz 2087 mS Pi-Zero 2982 mS Armmite F7 3117 mS MM+ @ 120MHz 4476 mS MM+ @ 100MHz 5278 mS MM2 @ 48MHz 7602 mS Armmite L4 @ 80MHz 8433 mS MM2 @ 40MHz 9134 mS Armmite L4 @ 48MHz 12858 mS |
||||
goc30![]() Guru ![]() Joined: 12/04/2017 Location: FrancePosts: 435 |
Hi Jim have-you source of purebasic prog? It is very quick (more than dos) thank |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
The purebasic code I started with is here https://www.purebasic.fr/english/viewtopic.php?f=27&t=72219 AS it stands it is for 64bit and uses threads so is faster than the example I posted. I change dit to single thread and 32 bit before porting to MMBasic Jim VK7JH MMedit |
||||
goc30![]() Guru ![]() Joined: 12/04/2017 Location: FrancePosts: 435 |
Hi Jim thank it work perfect On my PC it take 2 ms to compute (on Win8.1, 64bits & purebasic 5.70) on 32bits PC, I have an ASM error (line 854) ![]() |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
To run on 32 bit. First remove the machine code. The Basic line is there in a rem so that is easy. It makes no difference to the time taken. Next problem is the size of the default variable type. PureBasic defaults to integer which is 32 bits for 32bit PB and 64bit for the 64bit version. This is a good reason to never use .i Always use .l or .q and the size doesn't change between versions. Because the author didn't use EnableExplicit, it took a bit to sift through the code setting the types to .q which is what MMBasic uses so that's a good thing. I used EnableExplicit to make sure I found them all. The one place that caught me out was the divide. PurePasic used '/' but for integer divide in MMBasic you need '\'. Until I fixed that, the result was very strange indeed. Here is my 32 bit version of PB before porting. 2019-02-10_121120_calculate_Pi.zip Being based on 20 year old code, the conversion was easy. I have changed the printout function to include the time taken to do the formatting and printing. Another addition is a few time prints between function calls. Handy when you try for 20000 digits on a H7 . 0277722610 2544149221 5765045081 2067717357 1202718024 19950 2968106203 7765788371 6690910941 8074487814 0490755178 20000 Total computation time: 1683643 mS Time to format and print: 6869 mS Jim VK7JH MMedit |
||||
goc30![]() Guru ![]() Joined: 12/04/2017 Location: FrancePosts: 435 |
Hi jim I have tested your 32bit prog. it is good ![]() ![]() |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |