## Calculating and printing the many digits of PI

Just starting out? Need help? Post your questions and find answers here.
Derek Posts: 2357
Joined: Wed Apr 07, 2004 12:51 am
Location: England

### Re: Calculating and printing the many digits of PI

blueznl wrote:Derek, to me that looks like a bug, to be honest.
To be honest, I'd prefer it if it was a bug and that regardless of floating point or integer anything >=x.5 went up and anything <x.5 went down, so much easier. blueznl
PureBasic Expert Posts: 6076
Joined: Sat May 17, 2003 11:31 am
Contact:

### Re: Calculating and printing the many digits of PI

Actually, I think it is a bug. Look at the following:

Code: Select all

``````f.f = 0
a.f = 3
b.f = 1.5

i.l = 3.0 + 1.5
Debug i

m.l = f.f + 3.0 + 1.5
Debug m

x.l = f.f + 3 + 1.5
debug x
``````
According to Fred's own words the outcome of the two expressions above should be the same. The 3.0 should turn the expression evaluation into 'float' mode, just like the f.f does.

It almost looks like the FPU returns bankers rounding whilst the compiler applies 'round half up' on numeric (non-variable) expressions....

(Edit)

In fact, it does! Try the following:

Code: Select all

``````zero.f = 0
onehalf.f = 1.5
three.f = 3
four.f = 4

i.l = 3.0 + 1.5
Debug i

j.l = 4.0 + 1.5
Debug j

k.l = onehalf + three
Debug k

l.l = onehalf + four
Debug l
``````
Obviously I have no clue how it was coded in the compiler, but my suspicion is that the compiler tries to optimize 3.0 + 1.5 and uses a regular 'normal rounding' rule, whilst the other calculation is done inside the FPU and is then converted back to integer following some IEEE standard. It makes sense, but needs to be documented I think...
( PB5.xx Win10 x64 Asrock AB350 Pro4 Ryzen 1600X 32GB RAM Evo 840 GTX1060 )
( The path to enlightenment and the PureBasic Survival Guide right here... )
Derek Posts: 2357
Joined: Wed Apr 07, 2004 12:51 am
Location: England

### Re: Calculating and printing the many digits of PI

Indeed, perhaps the compiler shouldn't try to optimise constant floats but instead just leave it to the fpu to do when running, I wouldn't think it would cause too much of an impact on running speed of programs and would then be a consistant behavior.
collectordave Posts: 1241
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

### Re: Calculating and printing the many digits of PI

Hi

I do not know why i got interested in this but here is some ideas. My maths is not great after 50 years.

The first problem is to grab the digits that are being calculated. here is a little programme that does that.

Code: Select all

``````Global PiString.s =  ""
Global Count.i = 0
Global Precision.i = 30
Procedure CPI(Circ.i,Dia.i)

Count  + 1

PiString = PiString + Str(Circ/Dia)

Tried = Mod(Circ,dia)
Tried = Tried * 10

If Count < Precision
CPI(tried,dia)
EndIf

EndProcedure
Debug #PI
CPI(22,7)
Debug PiString
``````
It just does some long division with the old 22/7 bit.

I did find this on the net as well then converted it to PB

Code: Select all

``````
Global p16.d,pi.d,precision.i
Global pistr.s = ""
Debug #PI

p16 = 1
pi = 0
precision = 40

For k = 0 To precision
pi = pi +( 1.0/p16 * (4.0/(8*k + 1) - 2.0/(8*k + 4) - 1.0/(8*k + 5) - 1.0/(8*k+6)))

p16 = p16 * 16

Next k

Debug pi
Debug StrD(pi,16)
``````
Just cannot tie the two together. If anyone can please post here.
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
blueb Posts: 914
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

### Re: Calculating and printing the many digits of PI

from the excellent... http://rosettacode.org/wiki/Category:PureBasic

Code: Select all

``````;==================================================================
;
; Create a program to continually calculate and output the next digit of (pi). The program should continue
; forever (until it is aborted by the user) calculating and outputting each digit in succession. The output
; should be a decimal sequence beginning 3.14159265 ...
;==================================================================

;Calculate Pi, limited To ~24 M-digits For memory And speed reasons.

#SCALE = 10000
#ARRINT=  2000

Procedure Pi(Digits)
Protected First=#True, Text\$
Protected Carry, i, j, sum
Dim Arr(Digits)
For i=0 To Digits
Arr(i)=#ARRINT
Next
i=Digits
While i>0
sum=0
j=i
While j>0
sum*j+#SCALE*arr(j)
Arr(j)=sum%(j*2-1)
sum/(j*2-1)
j-1
Wend
Text\$ = RSet(Str(Carry+sum/#SCALE),4,"0")
If First
Text\$ = ReplaceString(Text\$,"3","3.")
First = #False
EndIf
Print(Text\$)
Carry=sum%#SCALE
i-14
Wend
EndProcedure

If OpenConsole()
SetConsoleCtrlHandler_(?Ctrl,#True)
Pi(24*1024*1024)
EndIf
End

Ctrl:
PrintN(#CRLF\$+"Ctrl-C was pressed")
End``````
Big Thanks to Demivec, and others for this.

I have collected all 500 or so tasks and a few tasks no longer compile in 5.42.
Once Demivec looks these over, I'd like to place them at another location.
Maybe RSBasic.de in case the Rosetta site disappears.
- It was too lonely at the top.

Current Machine: Win 10 Pro 64-bit, Dual Xeon E5-2670, 64 gigs ram, Geforce GTX 1660 Ti w/6 gigs ram
collectordave Posts: 1241
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

### Re: Calculating and printing the many digits of PI

That is brilliant thanks very much for the code and the link.
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
Keya Posts: 1864
Joined: Thu Jun 04, 2015 7:10 am

### Re: Calculating and printing the many digits of PI

earlier this year i memorized "C:\Program Files\genpi\genpi64.exe" to 34 places  collectordave Posts: 1241
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

### Re: Calculating and printing the many digits of PI

Just to complete this I have added a precision box, timer and the programme now outputs "Pi.txt" to allow it to be printed.

Enter the number of digits required in the box and click start. When done the time taken is displayed and you will find Pi.txt in the folder ready to be printed. The QuadsPerLine variable can be adjusted to set how many four digit sequences are printed across a line so adjust this for your paper width to print. I think 20 is about A4 portrait width.

Code: Select all

``````#SCALE = 10000
#ARRINT=  2000

Global Window_0

Global btnStart, btnCancel, strTime, txtTime

DigitsRequired = 1000

Procedure Pi()
Protected First=#True, Text\$
Protected Carry, i, j, sum
Iterations = 0
Digits = 24 * 1024
NumberOfDigits = 0
Dim Arr(Digits)
For i=0 To Digits
Arr(i)=#ARRINT
Next
i=Digits
While i>0
sum=0
j=i
While j>0
sum*j+#SCALE*arr(j)
Arr(j)=sum%(j*2-1)
sum/(j*2-1)
j-1
Wend
Text\$ = RSet(Str(Carry+sum/#SCALE),4,"0")
If First
Text\$ = ReplaceString(Text\$,"3","3.")
First = #False
EndIf

NumberOfDigits = NumberOfDigits + 4
If NumberOfDigits => DigitsRequired
Break
Else
If Iterations = QuadsPerLine - 1
WriteStringN(0, " " + text\$)
Iterations = 0
Else
WriteString(0, " " + text\$)
Iterations = Iterations + 1
EndIf
EndIf

Carry=sum%#SCALE
i-14
Wend
EndProcedure

Window_0 = OpenWindow(#PB_Any, 0, 0, 200, 110, "Pi Tester", #PB_Window_SystemMenu)
txtPrecision = TextGadget(#PB_Any, 10, 10, 70, 20, "Precision", #PB_Text_Right)
strPrecision = StringGadget(#PB_Any, 90, 10, 100, 20, "")
btnStart = ButtonGadget(#PB_Any, 90, 40, 100, 30, "Start")
strTime = StringGadget(#PB_Any, 90, 80, 100, 20, "")
txtTime = TextGadget(#PB_Any, 10, 80, 130, 20, "Time Taken")
Running = #False

Repeat
Event = WaitWindowEvent()

Select event

Case #PB_Event_CloseWindow
End

Case btnStart
MessageRequester("Precision Error","Maximum precision allowed = " + Str(24*1024*1024))
Else
If CreateFile(0, "Pi.txt")
ElapsedSeconds = ElapsedMilliseconds()
Running = #True
pi()
ElapsedSeconds = ElapsedMilliseconds()-ElapsedSeconds
Running = #False
CloseFile(0)
EndIf
EndIf