Code: Select all

`''=============================================================================`

#include "gmp.bi"

''=============================================================================

dim as double t1,t2

t1 = timer

#define PRECISION 3321921

dim as __mpf_struct a,b,t,p,aa,bb,tt,pp,pi

mpf_init2( @a, PRECISION )

mpf_init2( @b, PRECISION )

mpf_init2( @t, PRECISION )

mpf_init2( @p, PRECISION )

mpf_init2( @aa, PRECISION )

mpf_init2( @bb, PRECISION )

mpf_init2( @tt, PRECISION )

mpf_init2( @pp, PRECISION )

mpf_init2( @pi, PRECISION )

mpf_set_str( @a, "1.0", 10 )

mpf_set_str( @b, "2.0", 10 )

mpf_set_str( @t, "0.25", 10 )

mpf_set_str( @p, "1.0", 10 )

mpf_sqrt( @b, @b )

mpf_ui_div( @b, 1, @b )

for i as integer = 1 to 20

''--------------

'' aa = (a+b)/2

''--------------

mpf_add( @aa, @a, @b )

mpf_div_ui( @aa, @aa , 2 )

''----------------

'' bb = sqrt(a*b)

''----------------

mpf_mul( @bb, @a, @b )

mpf_sqrt( @bb, @bb )

''-------------------

'' tt = t-p*(a-aa)^2

''-------------------

mpf_sub( @tt, @a, @aa )

mpf_pow_ui( @tt, @tt, 2 )

mpf_mul( @tt, @tt, @p )

mpf_sub( @tt, @t, @tt )

''----------

'' pp = 2*p

''----------

mpf_mul_ui( @pp, @p, 2 )

''--------------------------------

'' a = aa, b = bb, t = tt, p = pp

''--------------------------------

mpf_swap( @a, @aa )

mpf_swap( @b, @bb )

mpf_swap( @t, @tt )

mpf_swap( @p, @pp )

next

''-------------------

'' pi ~= (a+b)^2/4*t

''-------------------

mpf_add( @pi, @a, @b )

mpf_pow_ui( @pi, @pi, 2 )

mpf_div_ui( @pi, @pi, 4 )

mpf_div( @pi, @pi, @t )

t2 = timer

gmp_printf( !"%.1000000Ff\n\n", @pi )

print t2-t1; " seconds"

sleep

To use the static library I copied it to my working directory and changed the name to differentiate it from the libgmp.dll.a import library in the FreeBASIC lib directory. I then copied gmp.bi to my working directory and modified the #inclib statement to match the name I selected for the static library, which was libgmp_static.a, so the statement was then:

#inclib "gmp_static"

I determined the minimum bits of precision that will produce the correct value of Pi experimentally. If the precision is too low then the digits at the end will be incorrect (usually but not necessarily zeros).

I derived the number of iterations required from the quadratic convergence of the algorithm.

Although the default stack size worked OK for much smaller numbers of digits, to calculate 1000000 digits I had to increase it by adding -t 3075 to the FBC command line. If the stack is too small, then depending on how much too small it is and/or the version of the library, the app may be terminated silently, or it may trigger an access-violation or stack-overflow exception.

Last 40 digits of 1000000:

3311646283 9963464604 2209010610 5779458151

Source: http://gc3.net84.net/pi.htm

On my 3.0GHz P4 the 1000000-digit calculation runs in ~59 seconds (where in a previous test with the VC dynamic library from the same page it ran in ~277 seconds).