Question Peter Voorthuysen · Jul 9, 2019

Calculate PI

Hi,

I am looking for an Objectscript example to calculate PI (3,14) with at least 100 Decimals.

There are many examples on the internet (https://rosettacode.org/wiki/Pi), but I want to use it for testing purposes.

Regards,

Peter van Voorthuysen

Comments

Jon Willeke · Jul 9, 2019

I would look at the implementations that do not depend on a "big number" package. Java and C# use BigInteger; Python uses long; Ada, C, and others use GMP; etc. You might try porting the Pascal implementation to ObjectScript. Where you see div, use the "" operator, and be aware of operator precedence.

0
Vitaliy Serdtsev · Jul 10, 2019

Translation of: BASIC256

<FONT COLOR="#ff0000">calcPI</FONT><FONT COLOR="#000000">(n=1000) </FONT><FONT COLOR="#0000ff">public </FONT><FONT COLOR="#800080">{ 
  </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">len </FONT><FONT COLOR="#000000">= 10*</FONT><FONT COLOR="#800000">n</FONT><FONT COLOR="#000000">\4,
    </FONT><FONT COLOR="#800000">needdecimal </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$$$YES</FONT><FONT COLOR="#000000">,
    </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">= 0,
    </FONT><FONT COLOR="#800000">predigit </FONT><FONT COLOR="#000000">= 0  </FONT><FONT COLOR="#008000">;# {First predigit is a 0}
   
  </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">j</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#800000">len </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">a</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">j</FONT><FONT COLOR="#000000">-1)=2 </FONT><FONT COLOR="#008000">;# {Start with 2s}
  
  </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">j</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#800000">n </FONT><FONT COLOR="#800080">{
    </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=0
    </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800000">len</FONT><FONT COLOR="#000000">:-1:1 </FONT><FONT COLOR="#800080">{
      </FONT><FONT COLOR="#008000">;#  {Work backwards}
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">x </FONT><FONT COLOR="#000000">= 10*</FONT><FONT COLOR="#800000">a</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">-1) + (</FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">),
        </FONT><FONT COLOR="#800000">a</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">-1)=</FONT><FONT COLOR="#800000">x</FONT><FONT COLOR="#000000">#(2</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">-1),
        </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800000">x</FONT><FONT COLOR="#000000">(2*</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">-1)
    </FONT><FONT COLOR="#800080">}
    </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">a</FONT><FONT COLOR="#000000">(0)=</FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">#10,
      </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">\10
    </FONT><FONT COLOR="#0000ff">i </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=9 </FONT><FONT COLOR="#800080">{
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">+ 1
    </FONT><FONT COLOR="#800080">}</FONT><FONT COLOR="#0000ff">elseif </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=10 </FONT><FONT COLOR="#800080">{
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">d </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">predigit</FONT><FONT COLOR="#000000">+1 </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#ff0000">outputd
      </FONT><FONT COLOR="#0000ff">i </FONT><FONT COLOR="#800000">nines</FONT><FONT COLOR="#000000">>0 </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">k </FONT><FONT COLOR="#000000">= 1:1:</FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">d </FONT><FONT COLOR="#000000">=  0 </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#ff0000">outputd
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">predigit </FONT><FONT COLOR="#000000">= 0, </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">= 0
    </FONT><FONT COLOR="#800080">}</FONT><FONT COLOR="#0000ff">else</FONT><FONT COLOR="#800080">{
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">d </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">predigit</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">predigit </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">q </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#ff0000">outputd
      </FONT><FONT COLOR="#0000ff">i </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#800080">{
        </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">k </FONT><FONT COLOR="#000000">= 1:1:</FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">d </FONT><FONT COLOR="#000000">= 9 </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#ff0000">outputd
        </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">= 0
      </FONT><FONT COLOR="#800080">}
    }
  }
  </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">predigit
  </FONT><FONT COLOR="#0000ff">q
   
</FONT><FONT COLOR="#ff0000">outputd</FONT><FONT COLOR="#000000">()
  </FONT><FONT COLOR="#0000ff">if </FONT><FONT COLOR="#800000">needdecimal </FONT><FONT COLOR="#800080">{
     </FONT><FONT COLOR="#0000ff">q</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#800000">d</FONT><FONT COLOR="#000000">=0
     </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">d</FONT><FONT COLOR="#000000">_</FONT><FONT COLOR="#008000">"."
     </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">needdecimal </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$$$NO
  </FONT><FONT COLOR="#800080">} </FONT><FONT COLOR="#0000ff">else </FONT><FONT COLOR="#800080">{
     </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">d
  </FONT><FONT COLOR="#800080">}
}</FONT>
The greater "n", the higher the accuracy.

If there is a lack of RAM, you can easily replace the local array "a" with globals ^||a or ^a.

0
Vitaliy Serdtsev  Jul 10, 2019 to Peter Voorthuysen

Translation of: LUA

<FONT COLOR="#ff0000">calcPILua</FONT><FONT COLOR="#000000">(n=1000) </FONT><FONT COLOR="#0000ff">public </FONT><FONT COLOR="#800080">{ 
  </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">len </FONT><FONT COLOR="#000000">= 10*</FONT><FONT COLOR="#800000">n</FONT><FONT COLOR="#000000">\3,
    </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">= 0,
    </FONT><FONT COLOR="#800000">predigit </FONT><FONT COLOR="#000000">= 0
  
  </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">j</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#800000">len </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">a</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">j</FONT><FONT COLOR="#000000">)=2
  
  </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">j</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#800000">n </FONT><FONT COLOR="#800080">{
    </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=0
    </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800000">len</FONT><FONT COLOR="#000000">:-1:1 </FONT><FONT COLOR="#800080">{
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">x </FONT><FONT COLOR="#000000">= 10*</FONT><FONT COLOR="#800000">a</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">) + (</FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000"></FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">),
        </FONT><FONT COLOR="#800000">a</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">)=</FONT><FONT COLOR="#800000">x</FONT><FONT COLOR="#000000">#(2</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">-1),
        </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800000">x</FONT><FONT COLOR="#000000">(2*</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">-1)
    </FONT><FONT COLOR="#800080">}
    </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">a</FONT><FONT COLOR="#000000">(1)=</FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">#10,
      </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">\10
    </FONT><FONT COLOR="#0000ff">i </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=9 </FONT><FONT COLOR="#800080">{
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">+ 1
    </FONT><FONT COLOR="#800080">}</FONT><FONT COLOR="#0000ff">elseif </FONT><FONT COLOR="#800000">q</FONT><FONT COLOR="#000000">=10 </FONT><FONT COLOR="#800080">{
      </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">predigit</FONT><FONT COLOR="#000000">+1
      </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">k </FONT><FONT COLOR="#000000">= 1:1:</FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#000000">0
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">predigit </FONT><FONT COLOR="#000000">= 0, </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">= 0
    </FONT><FONT COLOR="#800080">}</FONT><FONT COLOR="#0000ff">else</FONT><FONT COLOR="#800080">{
      </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">predigit
      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">predigit </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">q
      </FONT><FONT COLOR="#0000ff">i </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#800080">{
        </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">k </FONT><FONT COLOR="#000000">= 1:1:</FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#000000">9
        </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">nines </FONT><FONT COLOR="#000000">= 0
      </FONT><FONT COLOR="#800080">}
    }
  }
  </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">predigit
</FONT><FONT COLOR="#800080">}</FONT>
The result of this example is exactly the same as the result of the program C# (tested at n=10000).

0
Peter Voorthuysen  Jul 11, 2019 to Vitaliy Serdtsev

Thanks again, both routines work OK now.

Regards,

Peter

0
Vitaliy Serdtsev  Jul 10, 2019 to Vitaliy Serdtsev

I found out the reason for the difference in the result BASIC256:

Instead

len = 10*n\4,

must be

len = 10*n\3,

Error on site.

0
Jon Willeke  Jul 10, 2019 to Vitaliy Serdtsev

It occurs to me that the Visual Basic solution works with minimal modification as Caché Basic: weaken the DIM statements, change Debug.Print to Print, and replace the call to Format$().

Option Explicit

Const VECSIZE = 3350
Const BUFSIZE = 201
Dim buffer
Dim vect
Dim more, karray, num, k, l, n

  For n = 1 To VECSIZE
    vect(n) = 2
  Next n
  For n = 1 To BUFSIZE
    karray = 0
    For l = VECSIZE To 1 Step -1
      num = 100000 * vect(l) + karray * l
      karray = num \ (2 * l - 1)
      vect(l) = num - karray * (2 * l - 1)
    Next l
    k = karray \ 100000
    buffer(n) = more + k
    more = karray - k * 100000
  Next n
  Print buffer(1)
  Print "."
  l = 0
  For n = 2 To BUFSIZE
    Print Right("00000" & buffer(n), 5)
    l = l + 1
    If l = 10 Then
      l = 0
      Print 'line feed
    End If
  Next n
0
Stuart Salzer · Jul 15, 2019

I wrote this a while ago. Just ran on a MacBook Pro Mid 2015, 2.8 GHz Intel Core i7.

It computed the first 1000 digits in less than 1 minute, 2000 digits in 5 minute, 3000 digits, in 14 minute, 4000 digits in 32 minute, 5000 digits in 60 minute...

PI    ; SRS 2011-07-18
    ; Compute PI using Plouffe and Bellard algorithm, based upon "C" code
    ; found at <http://iweb.dl.sourceforge.net/project/projectpi/
    ; Digit%20Extraction%20Methods/Plouffe%20and%20Bellard%20v1/pi1_f.c>.
    KILL ^PI,^PRIME
    SET ^PI=-1
    FOR I=0:1:9 JOB C($INCREMENT(^PI))
    QUIT
C(p)    NEW $ETRAP SET $ETRAP="DO ^%ETN"
    SET n=p*9+1
    SET bign=+$TRANSLATE(n+20*$ZLN(10)/$ZLN(2),".","!")
    SET sum=0
    SET a=3 FOR  QUIT:a>(2*bign)  DO  SET a=$$NP(a)
    . SET vmax=+$PIECE($ZLN(2*bign)/$ZLN(a),".")
    . SET av=1 FOR i=1:1:vmax SET av=av*a
    . SET s=0,num=1,den=1,v=0,kq=1,kq2=1
    . FOR k=1:1:bign DO
    . . SET t=k
    . . IF kq'<a FOR  SET t=t\a,v=v-1 IF t#a SET kq=0 QUIT
    . . SET kq=kq+1,num=num*t#av
    . . SET t=2*k-1
    . . DO:kq2'<a 
    . . . IF kq2=a FOR  SET t=t\a,v=v+1 QUIT:t#a
    . . . SET kq2=kq2-a
    . . SET den=den*t#av,kq2=kq2+2
    . . DO:v>0
    . . . SET t=$$IM(den,av),t=t*num#av,t=t*k#av
    . . . FOR i=v+1:1:vmax SET t=t*a#av
    . . . SET s=s+t
    . . . SET:s'<av s=s-av
    . SET t=$$PM(10,n-1,av),s=s*t#av
    . SET sum=sum+(s/av),sum=+("."_$PIECE(sum,".",2))
    SET ^PI(p)=$EXTRACT($PIECE(sum,".",2)_"000000000",1,9)
    JOB C($INCREMENT(^PI))
    QUIT
NP(a)    NEW (a) FOR  SET r=$ORDER(^PRIME(a)) QUIT:r'=""  DO  QUIT:r'=""
    . LOCK ^PRIME 
    . SET r=$ORDER(^PRIME(a)) IF r'="" LOCK  QUIT
    . IF $DATA(^PRIME)=0 SET ^PRIME=3,^PRIME(2)="",^PRIME(3)="" LOCK  QUIT
    . FOR r=^PRIME:2 DO  IF pr SET ^PRIME(r)="" QUIT:r>a
    . . SET pr=1 FOR p=3:2:$ZSQR(r) IF r#p=0 SET pr=0 QUIT
    . SET ^PRIME=r
    . LOCK
    QUIT r
IM(x,y)    NEW (x,y)
    SET u=x,v=y,c=1,a=0
    FOR  SET q=v\u,t=c,c=a-(q*c),a=t,t=u,u=v-(q*u),v=t QUIT:u=0
    SET a=a#y
    SET:a<0 a=a+y
    QUIT a
PM(a,b,m)    NEW (a,b,m)
    SET r=1,aa=a
    FOR  SET:b#2 r=r*aa#m SET b=b\2 QUIT:b=0  SET aa=aa*aa#m
    QUIT r
 

0
Vitaliy Serdtsev  Jul 16, 2019 to Stuart Salzer

Intel i5-2400

10000 digits ~ 58 sec.

calcPI(n) public { 
  s $lb(len,nines,predigit,r)=$lb(10*n\3,0,0,"")
  
  i=1:1:len a(i)=2
  
  j=1:1:{
    q=0
    i=len:-1:1 x=10*a(i)+(q*i), a(i)=x#(2*i-1), q=x\(2*i-1)
    a(1)=q#10, q=q\10
    q=9 {
      nines=nines+1
    }elseif q=10 {
      r=r_(predigit+1)_$$repeat^%qarfunc(0,nines), predigit=0, nines=0
    }else{
      r=r_predigitpredigit=q
      s:nines r=r_$$repeat^%qarfunc(9,nines), nines=0
    }
  }
  r_predigit
}
0