Page 2 of 2

Re: Calculating and printing the many digits of PI

Posted: Mon Nov 15, 2010 9:04 pm
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. :)

Re: Calculating and printing the many digits of PI

Posted: Mon Nov 15, 2010 9:23 pm
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...

Re: Calculating and printing the many digits of PI

Posted: Mon Nov 15, 2010 10:17 pm
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.

Re: Calculating and printing the many digits of PI

Posted: Wed Mar 30, 2016 3:42 pm
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.

Re: Calculating and printing the many digits of PI

Posted: Wed Mar 30, 2016 5:08 pm
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.

Re: Calculating and printing the many digits of PI

Posted: Thu Mar 31, 2016 5:18 am
by collectordave
That is brilliant thanks very much for the code and the link.

Re: Calculating and printing the many digits of PI

Posted: Thu Mar 31, 2016 6:06 am
by Keya
earlier this year i memorized "C:\Program Files\genpi\genpi64.exe" to 34 places :oops: :D

Re: Calculating and printing the many digits of PI

Posted: Thu Mar 31, 2016 7:27 am
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