Calculating and printing the many digits of PI

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

Re: Calculating and printing the many digits of PI

Post by Derek »

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. :)
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6161
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Calculating and printing the many digits of PI

Post by blueznl »

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...
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Derek
Addict
Addict
Posts: 2356
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Re: Calculating and printing the many digits of PI

Post by Derek »

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
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Calculating and printing the many digits of PI

Post by collectordave »

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.
User avatar
blueb
Addict
Addict
Posts: 1041
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Calculating and printing the many digits of PI

Post by blueb »

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

Rosetta Task: PI

Code: Select all

;==================================================================
; Rosetta Task: PI
;
; 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.

System : PB 6.10 Beta 9 (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Calculating and printing the many digits of PI

Post by collectordave »

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.
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: Calculating and printing the many digits of PI

Post by Keya »

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

Re: Calculating and printing the many digits of PI

Post by collectordave »

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

Global ElapsedSeconds.d,Running.i,NumberOfDigits.i,DigitsRequired.i,QuadsPerLine.i,Iterations.i

DigitsRequired = 1000
QuadsPerLine = 20

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")
AddWindowTimer(Window_0, 1, 100)
Running = #False

Repeat
  Event = WaitWindowEvent()
  
  Select event
      
    Case #PB_Event_CloseWindow
      End

    Case #PB_Event_Gadget
      Select EventGadget()
        Case btnStart
          If Val(GetGadgetText(strPrecision)) > 24*1024*1024
            MessageRequester("Precision Error","Maximum precision allowed = " + Str(24*1024*1024))
          Else
            If CreateFile(0, "Pi.txt")
              DigitsRequired = Val(GetGadgetText(strPrecision))
              SetGadgetText(strTime,"")
              ElapsedSeconds = ElapsedMilliseconds() 
              Running = #True
              pi()
              ElapsedSeconds = ElapsedMilliseconds()-ElapsedSeconds
              Running = #False
              CloseFile(0) 
            EndIf
          EndIf
          SetGadgetText(strTime,StrD(ElapsedSeconds/1000) + " Secs")
          
        Case btnCancel
          Running = #False
      EndSelect
  EndSelect
  
ForEver

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.
Post Reply