Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 07:07 02 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Blueberry Pi

Author Message
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 07:20am 09 Feb 2019
Copy link to clipboard 
Print this post

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.

JimEdited by TassyJim 2019-02-10
VK7JH
MMedit
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 09:21am 09 Feb 2019
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 10315
Posted: 10:43am 09 Feb 2019
Copy link to clipboard 
Print this post

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: France
Posts: 435
Posted: 08:47pm 09 Feb 2019
Copy link to clipboard 
Print this post

Hi Jim

have-you source of purebasic prog?
It is very quick (more than dos)
thank
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 11:47pm 09 Feb 2019
Copy link to clipboard 
Print this post

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: France
Posts: 435
Posted: 01:45am 10 Feb 2019
Copy link to clipboard 
Print this post

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: Australia
Posts: 6283
Posted: 02:15am 10 Feb 2019
Copy link to clipboard 
Print this post

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.
  Quote  FUNCTION PrintOut()
LOCAL p$, i AS INTEGER, j AS INTEGER, ptime 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
ptime =
TIMER - stime - ctime
PRINT ""

PRINT " Total computation time: "+STR$(ctime)+" mS"
PRINT " Time to format and print: "+STR$(ptime)+" mS"
END FUNCTION


Another addition is a few time prints between function calls.
Handy when you try for 20000 digits on a H7
  Quote   x = atan239()
'------------ 16*atan(1/5)
PRINT STR$(TIMER - stime)+"mS so far"
x = atan51()
PRINT STR$(TIMER - stime)+"mS so far"
x = atan52()
PRINT STR$(TIMER - stime)+"mS so far"


.
0277722610 2544149221 5765045081 2067717357 1202718024 19950
2968106203 7765788371 6690910941 8074487814 0490755178 20000

Total computation time: 1683643 mS
Time to format and print: 6869 mS

JimEdited by TassyJim 2019-02-11
VK7JH
MMedit
 
goc30

Guru

Joined: 12/04/2017
Location: France
Posts: 435
Posted: 03:36am 10 Feb 2019
Copy link to clipboard 
Print this post

Hi jim
I have tested your 32bit prog. it is good . In debug mode it take 3 ms, and executable prog take... 0 ms (for 5000 digits, it take 63ms)

 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025