Version 10 of pi

Updated 2003-10-01 13:31:53

Abstractly, pi is the ratio between the circumference and the diameter of a circle. It can be proven that the number is irrational, so you'll never get an exact representation of its value in Tcl.

The best way to use it in Tcl is to create a global variable (called pi of course) which contains a reasonably accurate approximation and then use that variable throughout your program.

DKF -- If you don't want to use a global var, a proc can also be used:

 proc Pi {} {return 3.1415926535897931} ;# RS

atan provides a handy way to ask Tcl for the value of pi:

 % expr {atan(1) * 4}
 3.1415926535897931

MGS Actually, using acos() is (slightly) more efficient:

 % set tcl_precision 17
 17
 % expr {acos(-1)}
 3.1415926535897931

Does anyone have any data on which method is preferable from a numerical point of view?

IDG Both contain the assumption that the transcendental functions are accurate to the last ulp. In many math libraries this is not so. I think you are safer with a string representation:

 set pi 3.1415926535897931

AM This is certainly recommendable: that way you can be sure to get a value which is platform-independent or at least highly predictable.


GS (030927) Here is a small program ables to compute 2400 digits of pi:

 # pi-2400.tcl 
 # 2400 digits of pi with a spigot algorithm

 set e 0
 for {set b 0} {$b <= 8400} {incr b} {set f($b) 2000}
 for {set c 8400} {$c > 0} {incr c -14} {
    set d 0
    for {set b $c} {$b > 0} {incr b -1} {
       set g [expr 2*$b -1]
       set d [expr ($d*$b) + ($f($b)*10000)]
       set f($b) [expr round([expr fmod($d,$g)])]
       set d [expr $d/$g]
    }
    puts -nonewline [format "%.4i" [expr $e+($d/10000)]]
    flush stdout
    set e [expr round([expr fmod($d,10000)])]
 }  

It uses a spigot algorithm. More details in A spigot algorithm for the digits of pi, Stanley Rabinowitz and Stan Wagon, American Mathematical Monthly, March 1995, pp195-203.

MGS [2003/09/27] - Here's a more efficient version:

 set e 0
 for {set b 0} {$b <= 8400} {incr b} {set f($b) 2000}
 for {set c 8400} {$c > 0} {incr c -14} {
    set d 0
    for {set b $c} {$b > 0} {incr b -1} {
       set g [expr {2 * $b - 1}]
       set d [expr {($d*$b) + ($f($b)*10000)}]
       set f($b) [expr {round(fmod($d,$g))}]
       set d [expr {$d / $g}]
    }
    puts -nonewline [format "%.4i" [expr {$e+($d/10000)}]]
    flush stdout
    set e [expr {round(fmod($d,10000))}]
 }

AM The efficiency is gained by putting the expressions in braces - then [expr] can parse it once and store the result.


It might be amusing to implement the Bailey-Borwein-Plouffe algorithm, a digit-extraction algorithm for exactly calculating the digits of pi (http://mathworld.wolfram.com/Bailey-Borwein-PlouffeAlgorithm.html , http://www.cecm.sfu.ca/~pborwein/ ). Fortran source code is available at the latter site under "My Papers on Pi" (direct link: http://www.cecm.sfu.ca/~pborwein/PISTUFF/Apistuff.html ). Note that the algorithm provides hexadecimal digits, so conversion to decimal would have to be done explicitly if desired.

Albert Davidson Chou HotFusionMan at Yahoo.com


Math function help - Arts and Crafts of Tcl-Tk Programming - Category Mathematics