gmp 6.2.1 and mpfr 4.1.0

General FreeBASIC programming questions.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

gmp 6.2.1 and mpfr 4.1.0

Post by srvaldez »

here are the binaries for gmp-6.2.0 as of 2020-01-17 and mpfr-4.0.2
for anyone interested
here are gmp-6.2.1+mpfr-4.1.0
Last edited by srvaldez on Nov 17, 2023 14:36, edited 15 times in total.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: gmp 6.1.0

Post by Tourist Trap »

srvaldez wrote:here are the binaries for gmp-6.1.0
and mpfr-3.1.3
for anyone interested
Hi, can I ask you what is it for? I think not related to Gimp since it shares most of the material of GTK. Then what about the headers if those libs are in C, C++ (as usual)?
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: gmp 6.1.0

Post by D.J.Peters »

@Tourist Trap
GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating-point numbers.
There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on.
https://gmplib.org/

The MPFR library is a C library for multiple-precision floating-point computations with correct rounding.
MPFR is based on the GMP multiple-precision library.
http://www.mpfr.org/
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: gmp 6.1.0

Post by Tourist Trap »

@D.J.Peters

Thanks!
I've made some check in the documentation in the meanwhile and it mentions it with headers version number 4.1.4. It even comes with a little example (which is rarely the case with external libs).
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: gmp 6.1.0

Post by dodicat »

Thanks srvaldez.
I got the gmp static and bunged it into the lib/win32 folder.
gmp.bi has been modified a bit I see.
I had to put one line into my functions code to get it to work:

type mpf_t as __mpf_struct

Here are my functions again.

Code: Select all

#Include once "gmp.bi"

'functions
'sin,cos,tan,logtaylor,log,exp,power,atn,acos,asin,greater,equals,less
'absolute,Pi_ui

Dim Shared As Ulongint PRECISION 
'========= Just in case you forget to set_precision ==========
precision=60
mpf_set_default_prec( PRECISION*4 )
'========================================================
type mpf_t as __mpf_struct
Sub set_precision(n As Uinteger)
    PRECISION=n
    mpf_set_default_prec( PRECISION*4 )
End Sub

Function equals overload(a As mpf_t,b As mpf_t) As Integer
    If Mpf_cmp(@a,@b) = 0 Then Return -1
End Function

Function greater overload(a As mpf_t,b As mpf_t) As Integer 'a>b
    If equals(a,b) Then Return 0
    Dim As mpf_t Ab,diff
    mpf_init(@Ab)
    mpf_init(@diff)
    mpf_sub(@diff,@b,@a)
    mpf_abs(@Ab,@diff)
    If mpf_cmp(@Ab,@diff)=0 Then Return 0
    Return -1
End Function
'(byval as mpz_ptr, byval as mpz_srcptr, byval as mpz_srcptr)
'function _mod_(n1 as mpz_ptr,n2 as mpz_ptr ) as mpz_srcptr
'mpz_mod
'end function
Function less overload(a As mpf_t,b As mpf_t) As Integer 'a>b
    If equals(a,b) Then Return 0
    if greater(a,b) then return 0
    return -1
End Function

function Absolute overload(a As mpf_t) as  mpf_t
    Dim As mpf_t Ab
    mpf_init(@Ab)
    mpf_abs(@Ab,@a)
    return Ab
    end function



Function Pi_ui Overload(places As Uinteger) As mpf_t
    Dim As __mpf_struct a,b,t,p,aa,bb,tt,pp,pi
    mpf_init2( @a, 4*places)
    mpf_init2( @b, 4*places)
    mpf_init2( @t, 4*places)
    mpf_init2( @p, 4*places)
    mpf_init2( @aa,4*places)
    mpf_init2( @bb,4*places)
    mpf_init2( @tt,4*places)
    mpf_init2( @pp,4*places)
    mpf_init2( @pi,4*places)
    mpf_set_str( @a,"1",10)
    mpf_set_str( @b,"2",10):mpf_sqrt( @b, @b )
    mpf_set_str( @t,".25",10)
    mpf_set_str( @p,"1",10)
    mpf_ui_div( @b,1,@b)
    Do 
        mpf_add( @aa,  @a,  @b )
        mpf_div_ui( @aa, @aa , 2 )
        mpf_mul( @bb, @a, @b )
        mpf_sqrt( @bb, @bb )
        mpf_sub( @tt, @a, @aa )
        mpf_mul(@tt,@tt,@tt)
        mpf_mul( @tt, @tt, @p )
        mpf_sub( @tt, @t, @tt )
        mpf_mul_ui( @pp, @p, 2 )
        mpf_swap( @a, @aa )
        mpf_swap( @b, @bb )
        mpf_swap( @t, @tt )
        mpf_swap( @p, @pp )
    Loop Until  Mpf_cmp(@a,@aa) = 0
    mpf_add( @pi, @a, @b )
    mpf_mul(@pi,@pi,@pi)
    mpf_div_ui( @pi, @pi, 4 )
    mpf_div( @pi, @pi, @t )
    Return pi
End Function

Function _sin Overload(x As mpf_t) As mpf_t
    Dim As mpf_t inv,XX,Term,Accum,_x,p,temp2,fac
    mpf_init(@_x)
    mpf_set(@_x,@x)
    Dim As mpf_t pi2,circ,Ab
    mpf_init(@circ)
    mpf_init(@Ab)
    pi2=Pi_ui(Cuint(20))
    mpf_mul_ui(@circ,@pi2,2)
    mpf_abs(@Ab,@x)
    If greater(Ab,circ) Then
        '======== CENTRALIZE ==============
        'floor/ceil to centralize
        Dim As mpf_t tmp,tmp2
        mpf_init(@tmp2)
        mpf_init(@tmp)
        If precision>20 Then
            pi2=pi_ui(precision)
        End If
        mpf_mul_ui(@pi2,@pi2,2) 'got 2*pi
        mpf_div(@tmp,@_x,@pi2)
        mpf_set(@tmp2,@tmp) 
        mpf_trunc(@tmp,@tmp)     'int part
        mpf_sub(@tmp,@tmp2,@tmp) 'frac part
        mpf_mul(@tmp,@tmp,@pi2)
        mpf_set(@_x,@tmp)
    End If
    '==================================
    Dim As Integer sign(3):sign(3)=1
    Dim As Integer c=1
    mpf_init(@XX)
    mpf_init(@Term)
    mpf_init(@Accum)
    mpf_init(@p)
    mpf_init(@fac)
    mpf_init(@temp2)
    mpf_init_set(@accum,@_x)
    mpf_init_set_str(@fac,"1",10)
    mpf_init_set(@p,@_x)
    mpf_mul(@XX,@_x,@_x)
    Do 
        c=c+2
        Mpf_set(@temp2,@accum)
        mpf_mul_ui(@fac,@fac,c*(c-1))
        mpf_mul(@p,@p,@XX)
        mpf_div(@term,@p,@fac)
        If sign(c And 3) Then
            mpf_sub(@Accum,@temp2,@Term)
        Else
            mpf_add(@Accum,@temp2,@Term)
        End If
    Loop Until  Mpf_cmp(@accum,@temp2) = 0  
    Return accum
End Function
Function _cos Overload(x As mpf_t) As mpf_t
    Dim As mpf_t inv,XX,Term,Accum,_x,p,temp2,fac
    mpf_init(@_x)
    mpf_set(@_x,@x)
    Dim As mpf_t pi2,circ,AB
    mpf_init(@circ)
    mpf_init(@Ab)
    pi2=Pi_ui(Cuint(20))
    mpf_mul_ui(@circ,@pi2,2)
    mpf_abs(@Ab,@x)
    If greater(Ab,circ) Then
        '======== CENTRALIZE ==============
        'floor/ceil to centralize
        Dim As mpf_t tmp,tmp2
        mpf_init(@tmp2)
        mpf_init(@tmp)
        If precision>20 Then
            pi2=pi_ui(precision)
        End If
        mpf_mul_ui(@pi2,@pi2,2) 'got 2*pi
        mpf_div(@tmp,@_x,@pi2)
        mpf_set(@tmp2,@tmp) 
        mpf_trunc(@tmp,@tmp)     'int part
        mpf_sub(@tmp,@tmp2,@tmp) 'frac part
        mpf_mul(@tmp,@tmp,@pi2)
        mpf_set(@_x,@tmp)
    End If
    '==================================
    Dim As Integer sign(3):sign(2)=1
    Dim As Integer c
    mpf_init(@XX)
    mpf_init(@Term)
    mpf_init(@Accum)
    mpf_init(@p)
    mpf_init(@fac)
    mpf_init(@temp2)
    mpf_init_set_str(@accum,"1",10)
    mpf_init_set_str(@fac,"1",10)
    mpf_init_set_str(@p,"1",10)
    mpf_mul(@XX,@_x,@_x)
    Do 
        c=c+2
        Mpf_set(@temp2,@accum)
        mpf_mul_ui(@fac,@fac,c*(c-1))
        mpf_mul(@p,@p,@XX)
        mpf_div(@term,@p,@fac)
        If sign(c And 3) Then
            mpf_sub(@Accum,@temp2,@Term)
        Else
            mpf_add(@Accum,@temp2,@Term)
        End If
    Loop Until  Mpf_cmp(@accum,@temp2) = 0  
    Return accum
End Function
Function _tan Overload(x As mpf_t) As mpf_t
    Dim As mpf_t s,c,_x,ans
    mpf_init(@ans)
    mpf_init(@_x)
    mpf_set(@_x,@x)
    s=_sin(_x)
    c=_cos(_x)
    mpf_div(@ans,@s,@c)
    Return ans
End Function
Function _logTaylor(x As mpf_t) As mpf_t
    'taylor series
    '====================Log Guard==================
    Dim As mpf_t g,zero
    mpf_init(@g)
    mpf_set(@g,@x)
    mpf_init(@zero)
    mpf_init_set_str(@zero,"0",10)
    mpf_abs(@g,@g)
    If  Mpf_cmp(@g,@x) <> 0 Then  Exit Function
    If Mpf_cmp(@x,@zero) = 0 Then  Exit Function
    '=============================================
    Dim As Integer invflag
    Dim As  mpf_t Inv,XX,Term,Accum,strC,_x,tmp,tmp2
    Dim As mpf_t T,B,one,Q,two
    mpf_init(@two)
    mpf_init(@XX)
    mpf_init(@Q)
    mpf_init(@inv)
    mpf_init(@tmp)
    mpf_init(@tmp2)
    mpf_init(@accum)
    mpf_init(@term)
    mpf_init(@T)
    mpf_init(@B)
    mpf_init(@one)
    mpf_init(@_x)
    mpf_init_set_str(@one,"1",10)
    mpf_init_set_str(@two,"2",10)
    mpf_set(@_x,@x)
    If less(x,one) Then
        invflag=1
        mpf_div(@_x,@one,@_x)
    End If
    mpf_sub(@T,@_x,@one)
    mpf_add(@B,@_x,@one)
    mpf_div(@accum,@T,@B)
    mpf_div(@Q,@T,@B)
    Mpf_set(@tmp,@Q)
    Mpf_mul(@XX,@Q,@Q)
    Dim As Integer c=1
    Do 
        c=c+2
        Mpf_set(@tmp2,@tmp)
        mpf_mul(@Q,@Q,@XX)
        mpf_div_ui(@term,@Q,c)
        mpf_add(@Accum,@tmp,@Term)
        Mpf_swap(@tmp,@Accum)
    Loop Until Mpf_cmp(@tmp,@tmp2) = 0
    mpf_mul(@accum,@accum,@two)
    If invflag Then
        Dim As mpf_t minus1
        mpf_init(@minus1)
        mpf_init_set_str(@minus1,"-1",10)
        mpf_mul(@accum,@minus1,@accum)
        Return accum
    End If
    Return accum
End Function
Function _log Overload(x As mpf_t) As mpf_t
    '====================Log Guard==================
    Dim As mpf_t g=x,zero
    mpf_init(@zero)
    mpf_init_set_str(@zero,"0",10)
    mpf_abs(@g,@g)
    If  Mpf_cmp(@g,@x) <> 0 Then  Exit Function
    If Mpf_cmp(@x,@zero) = 0 Then  Exit Function
    '=============================================
    Dim As mpf_t approx,ans,logx,factor
    mpf_init(@approx)
    Mpf_set(@approx,@x)
    mpf_init(@factor)
    mpf_init_set_str(@factor,"8",10)
    mpf_init(@ans)
    mpf_sqrt(@approx,@approx)
    mpf_sqrt(@approx,@approx)
    mpf_sqrt(@approx,@approx)
    logx=_logTaylor(approx)
    mpf_mul(@ans,@factor,@logx)
    Return ans
End Function
Function _exp Overload(x As mpf_t) As mpf_t
    'taylor series
    Dim As  mpf_t fac,inv,_x,temp1,temp2,accum,strc,one,p,term
    mpf_init(@Inv)
    mpf_init(@fac)
    mpf_init(@_x)
    mpf_init(@temp1)
    mpf_init(@temp2)
    mpf_init(@accum)
    mpf_init(@strc)
    mpf_init(@one)
    mpf_init(@p)
    mpf_init(@term)
    mpf_init_set_str(@one,"1",10)
    mpf_init_set_str(@fac,"1",10)
    mpf_set(@_x,@x)
    mpf_init_set_str(@temp1,"1",10)
    mpf_init_set_str(@p,"1",10)'_x
    mpf_init_set_str(@accum,"1",10)
    Dim As Integer c
    Do
        c=c+1
        Mpf_set(@temp2,@accum)
        mpf_init_set_str(@strC,Str(c),10)
        mpf_mul(@fac,@fac,@strc)
        mpf_mul(@p,@p,@_x)
        mpf_div(@term,@p,@fac)
        mpf_add(@Accum,@temp2,@Term)
    Loop Until Mpf_cmp(@accum,@temp2) = 0
    Return accum
End Function
Function power Overload(a As mpf_t,p As mpf_t) As mpf_t
    'a^p= exp(p*log(a))
    '====================Power Guard==================
    Dim As mpf_t g,zero
    mpf_init(@g)
    Mpf_set(@g,@a)
    mpf_init(@zero)
    mpf_init_set_str(@zero,"0",10)
    mpf_abs(@g,@g)
    If  Mpf_cmp(@g,@a) <> 0 Then  Exit Function
    If Mpf_cmp(@a,@zero) = 0 Then  Exit Function
    '=============================================
    Dim As mpf_t loga,product,ans
    mpf_init(@product)
    loga=_log(a)
    mpf_mul(@product,@p,@loga)
    ans=_exp(product)
    Return ans
End Function
Function _Atn Overload(x As mpf_t) As mpf_t
    #macro ArctanTaylor(decnum)
    mpf_init(@Inv)
    mpf_init(@XX)
    mpf_init(@Term)
    mpf_init(@Accum)
    mpf_init(@strC)
    mpf_init(@_x)
    mpf_init(@mt)
    mpf_init(@mt2)
    mpf_init(@p)
    Mpf_set(@mt,@decnum)
    Mpf_set(@_x,@decnum)
    Mpf_set(@p,@decnum)
    mpf_mul(@XX,@_x,@_x)
    Do
        c=c+2
        Mpf_set(@mt2,@mt)
        mpf_set_str(@strC,Str(c),10)
        mpf_mul(@p,@p,@XX)
        mpf_div(@Term,@p,@strc)
        If sign(c And 3) Then
            mpf_sub(@Accum,@mt,@Term)
        Else
            mpf_add(@Accum,@mt,@Term)
        End If
        Mpf_swap(@mt,@Accum)
    Loop Until  Mpf_cmp(@mt,@mt2) = 0
    #endmacro
    Dim As Integer sign(3):sign(3)=1
    Dim As Uinteger c=1
    Dim As mpf_t Inv,XX,Term,Accum,_one,strC,_x,mt,mt2,p
    Dim As mpf_t _temp,one,_temp2,factor
    
    mpf_init(@_temp)
    mpf_init(@one)
    mpf_init(@factor)
    mpf_init(@_temp2)
    mpf_set(@_temp2,@x)
    mpf_init_set_str(@one,"1",10)
    Dim As Integer limit=16
    Dim As String P2=Str(2^limit)
    mpf_init_set_str(@factor,p2,10)
    For z As Integer=1 To limit
        mpf_mul(@_temp,@_temp2,@_temp2)
        mpf_add(@_temp,@_temp,@one)
        mpf_sqrt(@_temp,@_temp)
        mpf_add(@_temp,@_temp,@one)
        mpf_div(@_temp,@_temp2,@_temp)
        Mpf_set(@_temp2,@_temp)
    Next z
    ArctanTaylor(_temp)
    mpf_mul(@mt,@factor,@mt)
    Return mt
End Function
Function _Acos Overload(x As mpf_t) As mpf_t
    Dim As mpf_t  one,minusone,two,atn1,tail,T,B,term1,atnterm1,ans',_x,temp
    'ARCCOS = ATN(-x / SQR(-x * x + 1)) + 2 * ATN(1)
    '============= ARCCOS GUARD =========
    Var num= mpf_get_d(@x)
    If num>1 Then Exit Function
    If num<-1 Then Exit Function
    '========================
    mpf_init(@one)
    mpf_init(@two)
    mpf_init(@minusone)
    mpf_init(@tail)
    mpf_init(@T)
    mpf_init(@B)
    mpf_init(@term1)
    mpf_init(@ans)
    mpf_init_set_str(@one,"1",10)
    mpf_init_set_str(@minusone,"-1",10)
    mpf_init_set_str(@two,"2",10)
    atn1=_ATN(one)
    mpf_mul(@tail,@two,@atn1)  '2*atn(1)
    mpf_mul(@T,@minusone,@x)   '-x
    mpf_mul(@B,@x,@x) 'x*x
    If Mpf_cmp(@B,@one) = 0 Then
        'for 1 and -1  
        If mpf_cmp(@x,@minusone)=0 Then
            Dim As mpf_t four
            mpf_init(@four)
            mpf_init_set_str(@four,"4",10)
            mpf_mul(@four,@four,@atn1)
            Return four
        Else
            Dim As mpf_t zero
            mpf_init(@zero)
            mpf_init_set_str(@zero,"0",10)
            Return zero
        End If
    End If
    mpf_sub(@B,@one,@B)        '1-x*x
    mpf_sqrt(@B,@B)            'sqr(1-x*x)
    mpf_div(@term1,@T,@B)
    atnterm1=_ATN(term1)
    mpf_add(@ans,@atnterm1,@tail)
    Return ans
End Function
Function _Asin Overload(x As mpf_t) As mpf_t
    ' ARCSIN = ATN(x / SQR(-x * x + 1))
    '============= ARCSIN GUARD =========
    Var num= mpf_get_d(@x)
    If num>1 Then Exit Function
    If num<-1 Then Exit Function
    '========================
    Dim As mpf_t  one,T,B,term1,atnterm1,minusone
    mpf_init(@minusone)
    mpf_init(@one)
    mpf_init(@T)
    mpf_init(@B)
    mpf_init(@term1)
    mpf_init_set_str(@one,"1",10)
    mpf_init_set_str(@minusone,"-1",10)
    mpf_set(@T,@x)
    'T=x
    mpf_mul(@B,@x,@x)          'x*x
    'for 1 and -1
    If Mpf_cmp(@B,@one) = 0 Then
        Dim As mpf_t two,atn1
        mpf_init(@two)
        mpf_init_set_str(@two,"2",10)
        atn1=_atn(one)
        If mpf_cmp(@x,@minusone)=0 Then
            mpf_mul(@two,@two,@atn1)
            mpf_mul(@two,@two,@minusone)
            Return two
        Else
            mpf_mul(@two,@two,@atn1)
            Return two
        End If
    End If
    mpf_sub(@B,@one,@B)        '1-x*x
    mpf_sqrt(@B,@B)            'sqr(1-x*x)
    mpf_div(@term1,@T,@B)
    atnterm1=_ATN(term1)
    Return atnterm1
End Function


'===========================================================================
'=======================   OVERLOADS  FOR STRINGS ===============================
Dim Shared As Zstring * 100000000 outtext

Function Pi_ui Overload(places As Integer) As String
    Dim As Mpf_t ans
    Var pl=Cuint(places)
    ans=pi_ui(pl)
    gmp_sprintf( @outtext,"%." & pl & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _sin Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_sin(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _cos Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_cos(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _tan Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_tan(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _log Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_log(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _exp Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_exp(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function power Overload(a As String,p As String) As String
    Dim As Mpf_t _x,ans,pow
    mpf_init(@_x)
    mpf_init_set_str(@_x,a,10)
    mpf_init(@pow)
    mpf_init_set_str(@pow,p,10)
    ans=power(_x,pow)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _Atn Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_Atn(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _Acos Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_Acos(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _Asin Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_Asin(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function


Function factorial(n As Uinteger) As String 'Automatic precision
    Dim As __mpz_struct Intanswer
    mpz_init2( @Intanswer,0)
    mpz_set_str( @Intanswer,"",10)
    mpz_fac_ui(@Intanswer,n)
    gmp_sprintf( @outtext,"%Zi", @Intanswer )
    Return Trim(outtext)
End Function

function _mod(n1 as string,n2 as string) as string
   dim as __mpz_struct answer,mn1,mn2
   mpz_init2( @answer,0)
    mpz_init2( @mn1,0)
     mpz_init2( @mn2,0)
   mpz_init_set_str( @answer,"",10)
   mpz_init_set_str( @mn1,n1,10)
   mpz_init_set_str( @mn2,n2,10)
   mpz_mod(@answer,@mn1,@mn2)
   gmp_sprintf( @outtext,"%Zi", @answer )
    Return Trim(outtext)
   
end function

Function Sqrroot(number As String,decimals As Uinteger=PRECISION) As String'precision parameter
    if instr(number,"-") then exit function
    Dim As __mpf_struct num,FloatAnswer
    Dim As Integer LN=Len(number)
    mpf_init2(@num,4*Ln):mpf_init2(@FloatAnswer,4*Ln)
    mpf_set_str(@num,number,10)
    mpf_sqrt( @FloatAnswer,@num)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer )
    Return Trim(outtext)
End Function

Function mult(number1 As String,number2 As String) As String'Automatic precision
    Dim As Integer Ln1=Len(number1),Ln2=Len(number2)
    Dim As __mpf_struct num1,num2,FloatAnswer
    mpf_init2( @num1,4*(Ln1+Ln2+1) )
    mpf_init2( @num2,4*(Ln1+Ln2+1) )
    mpf_init2(@Floatanswer,4*(Ln1+Ln2+1))
    Ln1=Instr(1,number1,"."):Ln2=Instr(1,number2,".")
    var decimals=Len(Mid(number1,Ln1+1))+Len(Mid(number2,Ln2+1))+1
    mpf_set_str( @num1,number1,10)
    mpf_set_str( @num2,number2,10)
    mpf_mul(@Floatanswer,@num1,@num2)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer )
    var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function

'precision parameter
Function divide(number1 As String,number2 As String,decimals As Uinteger=PRECISION) As String
    Dim As Integer Ln1=Len(number1),Ln2=Len(number2),Ln
    If Ln1>=Ln2 Then  Ln=Ln1 Else Ln=Ln2
    Dim As __mpf_struct num1,num2,FloatAnswer
    mpf_init2( @num1,4*(Ln+1) )
    mpf_init2( @num2,4*(Ln+1) )
    mpf_init2(@Floatanswer,4*(Ln+1)+4*decimals)
    mpf_set_str( @num1,number1,10)
    mpf_set_str( @num2,number2,10)
    mpf_div(@Floatanswer,@num1,@num2)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer)
    Return Trim(outtext)
End Function

Function  Power Overload(number As String,n As Uinteger) As String'automatic precision
    #define dp 3321921
    Dim As __mpf_struct _number,FloatAnswer
    Dim As Ulongint ln=Len(number)*(n)*4
    If ln>dp Then ln=dp
    mpf_init2(@FloatAnswer,ln)
    mpf_init2(@_number,ln) 'or 4*len(number)
    mpf_set_str(@_number,number,10)
    mpf_pow_ui(@Floatanswer,@_number,n)
    gmp_sprintf( @outtext,"%." & Str(n) & "Ff",@FloatAnswer )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function

Function plus(number1 As String,number2 As String) As String'automatic precision
    Dim As Integer Ln1=Len(number1),Ln2=Len(number2),decimals,Ln
    If Ln1>=Ln2 Then Ln=Ln1 Else Ln=Ln2
    Ln=ln+1
    Dim As __mpf_struct num1,num2,FloatAnswer
    mpf_init2( @num1,4*(Ln1+1) )
    mpf_init2( @num2,4*(Ln2+1) )
    mpf_init2(@Floatanswer,4*(Ln))
    mpf_set_str( @num1,number1,10)
    mpf_set_str( @num2,number2,10)
    Ln1=Instr(1,number1,"."):Ln2=Instr(1,number2,".")
    If Ln1 Or Ln2 Then
        decimals=Len(Mid(number1,Ln1+1))+Len(Mid(number2,Ln2+1))+1
    End If
    mpf_add(@Floatanswer,@num1,@num2)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer )
    var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function

Function minus(number1 As String,number2 As String) As String'automatic precision
    Dim As Integer Ln1=Len(number1),Ln2=Len(number2),decimals,Ln
    If Ln1>=Ln2 Then  Ln=Ln1 Else Ln=Ln2
    Ln=ln+1
    Dim As __mpf_struct num1,num2,FloatAnswer
    mpf_init2( @num1,4*(Ln1+1) )
    mpf_init2( @num2,4*(Ln2+1) )
    mpf_init2(@Floatanswer,4*(Ln))
    mpf_set_str( @num1,number1,10)
    mpf_set_str( @num2,number2,10)
    Ln1=Instr(1,number1,"."):Ln2=Instr(1,number2,".")
    If Ln1 Or Ln2 Then
        decimals=Len(Mid(number1,Ln1+1))+Len(Mid(number2,Ln2+1))+1
    End If
    mpf_sub(@Floatanswer,@num1,@num2)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer )
    var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function
function Absolute overload(a As string) as  string
    Dim As __mpf_struct Ab,Floatanswer
     mpf_init2( @FloatAnswer,4*precision )
     mpf_init2( @Ab,4*precision )
     mpf_set_str( @Ab,a,10)
     mpf_abs(@FloatAnswer,@Ab)
     gmp_sprintf( @outtext,"%." & Str(precision) & "Ff",@FloatAnswer )
    var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
end function

function greater overload(a as string,b as string) as integer
   dim as mpf_t ma,mb
   mpf_init2(@ma,4*precision)
   mpf_init2(@mb,4*precision)
    mpf_set_str( @ma,a,10)
    mpf_set_str( @mb,b,10)
    return greater(ma,mb)
end function
function equals overload(a as string,b as string) as integer
       dim as mpf_t ma,mb
   mpf_init2(@ma,4*precision)
   mpf_init2(@mb,4*precision)
    mpf_set_str( @ma,a,10)
    mpf_set_str( @mb,b,10)
    return equals(ma,mb)
end function

function less overload(a as string,b as string) as integer
   if equals(a,b) then return 0
   if greater(a,b) then return 0
   return -1
    end function

'======================== TESTS ===============================
''Extern gmp_version Alias "__gmp_version" As Zstring Ptr
Print "GMP version ";*gmp_version
set_precision(2000)

Print "256.00098 ^ -6.003"
Print "press a key"
Sleep
Dim As String num="256.00098",pow="-6.003"
Print "power ";num;" to ";pow
Print power(num,pow)
Print "Float check"
Print Val(num)^Val(pow)
Print "Now pi to 5000 places"
Print "Press a key"
Sleep
Print
Print
Print "pi from Pi_ui"
Print Pi_ui(5000)
Print "Press a key"
Sleep
Print

Print
Print
Print "Log(50000.5)"
Print _log("50000.5")
Print
Print "Float check"
Print Str(Log(50000.5))
Print "Press a key"
Sleep
Print 


set_precision(60)
Print
Print "sin(.33)"
Print _sin(".33"),Sin(.33)
Print
Print "cos(-300.988)"
Print _cos("-300.988"),Cos(-300.988)
Print
Print "tan(1000000)"
Print _tan("1000000"),Tan(1000000)
Print
Print " Now -- 2 to power 1000000"
Print "press a key"
Sleep
Print
Print power("2",1000000)
Print
Print "now  1/5.870099330099900999 to 10000 places"
Print "press a key"
Sleep
var ans=divide("1","5.870099330099900999",10000)
Print ans
Print "Check length  ";Len(ans)
Print "e to 4000 places"
Print "press a key"
Sleep
set_precision(4000)
print _exp("1")

Print
Print "Last test, acos(-1), which is pi"
Print "press a key"
Sleep
Print _acos("-1")
Print "Done"
dim as string g="-56.99"
print absolute(g)

sleep
 
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: gmp 6.1.0

Post by srvaldez »

thank you dodicat for the trig functions, I added them to my gmp overloaded functions.

Code: Select all

#Include once "gmp.bi"

'the following functions are by dodicat
'sin,cos,tan,logtaylor,log,exp,power,atn,acos,asin,greater,equals,less
'absolute,Pi_ui

Dim Shared As Ulongint PRECISION 
'========= Just in case you forget to set_precision ==========
precision=60
mpf_set_default_prec( PRECISION*4 )
'========================================================
type mpf_t as __mpf_struct
Sub set_precision(n As Uinteger)
    PRECISION=n
    mpf_set_default_prec( PRECISION*4 )
End Sub

Function equals overload(a As mpf_t,b As mpf_t) As Integer
    If Mpf_cmp(@a,@b) = 0 Then Return -1
End Function

Function greater overload(a As mpf_t,b As mpf_t) As Integer 'a>b
    If equals(a,b) Then Return 0
    Dim As mpf_t Ab,diff
    mpf_init(@Ab)
    mpf_init(@diff)
    mpf_sub(@diff,@b,@a)
    mpf_abs(@Ab,@diff)
    If mpf_cmp(@Ab,@diff)=0 Then Return 0
    Return -1
End Function
'(byval as mpz_ptr, byval as mpz_srcptr, byval as mpz_srcptr)
'function _mod_(n1 as mpz_ptr,n2 as mpz_ptr ) as mpz_srcptr
'mpz_mod
'end function
Function less overload(a As mpf_t,b As mpf_t) As Integer 'a>b
    If equals(a,b) Then Return 0
    if greater(a,b) then return 0
    return -1
End Function

function Absolute overload(a As mpf_t) as  mpf_t
    Dim As mpf_t Ab
    mpf_init(@Ab)
    mpf_abs(@Ab,@a)
    return Ab
    end function



Function Pi_ui Overload(places As Uinteger) As mpf_t
    Dim As __mpf_struct a,b,t,p,aa,bb,tt,pp,pi
    mpf_init2( @a, 4*places)
    mpf_init2( @b, 4*places)
    mpf_init2( @t, 4*places)
    mpf_init2( @p, 4*places)
    mpf_init2( @aa,4*places)
    mpf_init2( @bb,4*places)
    mpf_init2( @tt,4*places)
    mpf_init2( @pp,4*places)
    mpf_init2( @pi,4*places)
    mpf_set_str( @a,"1",10)
    mpf_set_str( @b,"2",10):mpf_sqrt( @b, @b )
    mpf_set_str( @t,".25",10)
    mpf_set_str( @p,"1",10)
    mpf_ui_div( @b,1,@b)
    Do 
        mpf_add( @aa,  @a,  @b )
        mpf_div_ui( @aa, @aa , 2 )
        mpf_mul( @bb, @a, @b )
        mpf_sqrt( @bb, @bb )
        mpf_sub( @tt, @a, @aa )
        mpf_mul(@tt,@tt,@tt)
        mpf_mul( @tt, @tt, @p )
        mpf_sub( @tt, @t, @tt )
        mpf_mul_ui( @pp, @p, 2 )
        mpf_swap( @a, @aa )
        mpf_swap( @b, @bb )
        mpf_swap( @t, @tt )
        mpf_swap( @p, @pp )
    Loop Until  Mpf_cmp(@a,@aa) = 0
    mpf_add( @pi, @a, @b )
    mpf_mul(@pi,@pi,@pi)
    mpf_div_ui( @pi, @pi, 4 )
    mpf_div( @pi, @pi, @t )
    Return pi
End Function

Function _sin Overload(x As mpf_t) As mpf_t
    Dim As mpf_t inv,XX,Term,Accum,_x,p,temp2,fac
    mpf_init(@_x)
    mpf_set(@_x,@x)
    Dim As mpf_t pi2,circ,Ab
    mpf_init(@circ)
    mpf_init(@Ab)
    pi2=Pi_ui(Cuint(20))
    mpf_mul_ui(@circ,@pi2,2)
    mpf_abs(@Ab,@x)
    If greater(Ab,circ) Then
        '======== CENTRALIZE ==============
        'floor/ceil to centralize
        Dim As mpf_t tmp,tmp2
        mpf_init(@tmp2)
        mpf_init(@tmp)
        If precision>20 Then
            pi2=pi_ui(precision)
        End If
        mpf_mul_ui(@pi2,@pi2,2) 'got 2*pi
        mpf_div(@tmp,@_x,@pi2)
        mpf_set(@tmp2,@tmp) 
        mpf_trunc(@tmp,@tmp)     'int part
        mpf_sub(@tmp,@tmp2,@tmp) 'frac part
        mpf_mul(@tmp,@tmp,@pi2)
        mpf_set(@_x,@tmp)
    End If
    '==================================
    Dim As Integer sign(3):sign(3)=1
    Dim As Integer c=1
    mpf_init(@XX)
    mpf_init(@Term)
    mpf_init(@Accum)
    mpf_init(@p)
    mpf_init(@fac)
    mpf_init(@temp2)
    mpf_init_set(@accum,@_x)
    mpf_init_set_str(@fac,"1",10)
    mpf_init_set(@p,@_x)
    mpf_mul(@XX,@_x,@_x)
    Do 
        c=c+2
        Mpf_set(@temp2,@accum)
        mpf_mul_ui(@fac,@fac,c*(c-1))
        mpf_mul(@p,@p,@XX)
        mpf_div(@term,@p,@fac)
        If sign(c And 3) Then
            mpf_sub(@Accum,@temp2,@Term)
        Else
            mpf_add(@Accum,@temp2,@Term)
        End If
    Loop Until  Mpf_cmp(@accum,@temp2) = 0  
    Return accum
End Function
Function _cos Overload(x As mpf_t) As mpf_t
    Dim As mpf_t inv,XX,Term,Accum,_x,p,temp2,fac
    mpf_init(@_x)
    mpf_set(@_x,@x)
    Dim As mpf_t pi2,circ,AB
    mpf_init(@circ)
    mpf_init(@Ab)
    pi2=Pi_ui(Cuint(20))
    mpf_mul_ui(@circ,@pi2,2)
    mpf_abs(@Ab,@x)
    If greater(Ab,circ) Then
        '======== CENTRALIZE ==============
        'floor/ceil to centralize
        Dim As mpf_t tmp,tmp2
        mpf_init(@tmp2)
        mpf_init(@tmp)
        If precision>20 Then
            pi2=pi_ui(precision)
        End If
        mpf_mul_ui(@pi2,@pi2,2) 'got 2*pi
        mpf_div(@tmp,@_x,@pi2)
        mpf_set(@tmp2,@tmp) 
        mpf_trunc(@tmp,@tmp)     'int part
        mpf_sub(@tmp,@tmp2,@tmp) 'frac part
        mpf_mul(@tmp,@tmp,@pi2)
        mpf_set(@_x,@tmp)
    End If
    '==================================
    Dim As Integer sign(3):sign(2)=1
    Dim As Integer c
    mpf_init(@XX)
    mpf_init(@Term)
    mpf_init(@Accum)
    mpf_init(@p)
    mpf_init(@fac)
    mpf_init(@temp2)
    mpf_init_set_str(@accum,"1",10)
    mpf_init_set_str(@fac,"1",10)
    mpf_init_set_str(@p,"1",10)
    mpf_mul(@XX,@_x,@_x)
    Do 
        c=c+2
        Mpf_set(@temp2,@accum)
        mpf_mul_ui(@fac,@fac,c*(c-1))
        mpf_mul(@p,@p,@XX)
        mpf_div(@term,@p,@fac)
        If sign(c And 3) Then
            mpf_sub(@Accum,@temp2,@Term)
        Else
            mpf_add(@Accum,@temp2,@Term)
        End If
    Loop Until  Mpf_cmp(@accum,@temp2) = 0  
    Return accum
End Function
Function _tan Overload(x As mpf_t) As mpf_t
    Dim As mpf_t s,c,_x,ans
    mpf_init(@ans)
    mpf_init(@_x)
    mpf_set(@_x,@x)
    s=_sin(_x)
    c=_cos(_x)
    mpf_div(@ans,@s,@c)
    Return ans
End Function
Function _logTaylor(x As mpf_t) As mpf_t
    'taylor series
    '====================Log Guard==================
    Dim As mpf_t g,zero
    mpf_init(@g)
    mpf_set(@g,@x)
    mpf_init(@zero)
    mpf_init_set_str(@zero,"0",10)
    mpf_abs(@g,@g)
    If  Mpf_cmp(@g,@x) <> 0 Then  Exit Function
    If Mpf_cmp(@x,@zero) = 0 Then  Exit Function
    '=============================================
    Dim As Integer invflag
    Dim As  mpf_t Inv,XX,Term,Accum,strC,_x,tmp,tmp2
    Dim As mpf_t T,B,one,Q,two
    mpf_init(@two)
    mpf_init(@XX)
    mpf_init(@Q)
    mpf_init(@inv)
    mpf_init(@tmp)
    mpf_init(@tmp2)
    mpf_init(@accum)
    mpf_init(@term)
    mpf_init(@T)
    mpf_init(@B)
    mpf_init(@one)
    mpf_init(@_x)
    mpf_init_set_str(@one,"1",10)
    mpf_init_set_str(@two,"2",10)
    mpf_set(@_x,@x)
    If less(x,one) Then
        invflag=1
        mpf_div(@_x,@one,@_x)
    End If
    mpf_sub(@T,@_x,@one)
    mpf_add(@B,@_x,@one)
    mpf_div(@accum,@T,@B)
    mpf_div(@Q,@T,@B)
    Mpf_set(@tmp,@Q)
    Mpf_mul(@XX,@Q,@Q)
    Dim As Integer c=1
    Do 
        c=c+2
        Mpf_set(@tmp2,@tmp)
        mpf_mul(@Q,@Q,@XX)
        mpf_div_ui(@term,@Q,c)
        mpf_add(@Accum,@tmp,@Term)
        Mpf_swap(@tmp,@Accum)
    Loop Until Mpf_cmp(@tmp,@tmp2) = 0
    mpf_mul(@accum,@accum,@two)
    If invflag Then
        Dim As mpf_t minus1
        mpf_init(@minus1)
        mpf_init_set_str(@minus1,"-1",10)
        mpf_mul(@accum,@minus1,@accum)
        Return accum
    End If
    Return accum
End Function
Function _log Overload(x As mpf_t) As mpf_t
    '====================Log Guard==================
    Dim As mpf_t g=x,zero
    mpf_init(@zero)
    mpf_init_set_str(@zero,"0",10)
    mpf_abs(@g,@g)
    If  Mpf_cmp(@g,@x) <> 0 Then  Exit Function
    If Mpf_cmp(@x,@zero) = 0 Then  Exit Function
    '=============================================
    Dim As mpf_t approx,ans,logx,factor
    mpf_init(@approx)
    Mpf_set(@approx,@x)
    mpf_init(@factor)
    mpf_init_set_str(@factor,"8",10)
    mpf_init(@ans)
    mpf_sqrt(@approx,@approx)
    mpf_sqrt(@approx,@approx)
    mpf_sqrt(@approx,@approx)
    logx=_logTaylor(approx)
    mpf_mul(@ans,@factor,@logx)
    Return ans
End Function
Function _exp Overload(x As mpf_t) As mpf_t
    'taylor series
    Dim As  mpf_t fac,inv,_x,temp1,temp2,accum,strc,one,p,term
    mpf_init(@Inv)
    mpf_init(@fac)
    mpf_init(@_x)
    mpf_init(@temp1)
    mpf_init(@temp2)
    mpf_init(@accum)
    mpf_init(@strc)
    mpf_init(@one)
    mpf_init(@p)
    mpf_init(@term)
    mpf_init_set_str(@one,"1",10)
    mpf_init_set_str(@fac,"1",10)
    mpf_set(@_x,@x)
    mpf_init_set_str(@temp1,"1",10)
    mpf_init_set_str(@p,"1",10)'_x
    mpf_init_set_str(@accum,"1",10)
    Dim As Integer c
    Do
        c=c+1
        Mpf_set(@temp2,@accum)
        mpf_init_set_str(@strC,Str(c),10)
        mpf_mul(@fac,@fac,@strc)
        mpf_mul(@p,@p,@_x)
        mpf_div(@term,@p,@fac)
        mpf_add(@Accum,@temp2,@Term)
    Loop Until Mpf_cmp(@accum,@temp2) = 0
    Return accum
End Function
Function power Overload(a As mpf_t,p As mpf_t) As mpf_t
    'a^p= exp(p*log(a))
    '====================Power Guard==================
    Dim As mpf_t g,zero
    mpf_init(@g)
    Mpf_set(@g,@a)
    mpf_init(@zero)
    mpf_init_set_str(@zero,"0",10)
    mpf_abs(@g,@g)
    If  Mpf_cmp(@g,@a) <> 0 Then  Exit Function
    If Mpf_cmp(@a,@zero) = 0 Then  Exit Function
    '=============================================
    Dim As mpf_t loga,product,ans
    mpf_init(@product)
    loga=_log(a)
    mpf_mul(@product,@p,@loga)
    ans=_exp(product)
    Return ans
End Function
Function _Atn Overload(x As mpf_t) As mpf_t
    #macro ArctanTaylor(decnum)
    mpf_init(@Inv)
    mpf_init(@XX)
    mpf_init(@Term)
    mpf_init(@Accum)
    mpf_init(@strC)
    mpf_init(@_x)
    mpf_init(@mt)
    mpf_init(@mt2)
    mpf_init(@p)
    Mpf_set(@mt,@decnum)
    Mpf_set(@_x,@decnum)
    Mpf_set(@p,@decnum)
    mpf_mul(@XX,@_x,@_x)
    Do
        c=c+2
        Mpf_set(@mt2,@mt)
        mpf_set_str(@strC,Str(c),10)
        mpf_mul(@p,@p,@XX)
        mpf_div(@Term,@p,@strc)
        If sign(c And 3) Then
            mpf_sub(@Accum,@mt,@Term)
        Else
            mpf_add(@Accum,@mt,@Term)
        End If
        Mpf_swap(@mt,@Accum)
    Loop Until  Mpf_cmp(@mt,@mt2) = 0
    #endmacro
    Dim As Integer sign(3):sign(3)=1
    Dim As Uinteger c=1
    Dim As mpf_t Inv,XX,Term,Accum,_one,strC,_x,mt,mt2,p
    Dim As mpf_t _temp,one,_temp2,factor
    
    mpf_init(@_temp)
    mpf_init(@one)
    mpf_init(@factor)
    mpf_init(@_temp2)
    mpf_set(@_temp2,@x)
    mpf_init_set_str(@one,"1",10)
    Dim As Integer limit=16
    Dim As String P2=Str(2^limit)
    mpf_init_set_str(@factor,p2,10)
    For z As Integer=1 To limit
        mpf_mul(@_temp,@_temp2,@_temp2)
        mpf_add(@_temp,@_temp,@one)
        mpf_sqrt(@_temp,@_temp)
        mpf_add(@_temp,@_temp,@one)
        mpf_div(@_temp,@_temp2,@_temp)
        Mpf_set(@_temp2,@_temp)
    Next z
    ArctanTaylor(_temp)
    mpf_mul(@mt,@factor,@mt)
    Return mt
End Function
Function _Acos Overload(x As mpf_t) As mpf_t
    Dim As mpf_t  one,minusone,two,atn1,tail,T,B,term1,atnterm1,ans',_x,temp
    'ARCCOS = ATN(-x / SQR(-x * x + 1)) + 2 * ATN(1)
    '============= ARCCOS GUARD =========
    Var num= mpf_get_d(@x)
    If num>1 Then Exit Function
    If num<-1 Then Exit Function
    '========================
    mpf_init(@one)
    mpf_init(@two)
    mpf_init(@minusone)
    mpf_init(@tail)
    mpf_init(@T)
    mpf_init(@B)
    mpf_init(@term1)
    mpf_init(@ans)
    mpf_init_set_str(@one,"1",10)
    mpf_init_set_str(@minusone,"-1",10)
    mpf_init_set_str(@two,"2",10)
    atn1=_ATN(one)
    mpf_mul(@tail,@two,@atn1)  '2*atn(1)
    mpf_mul(@T,@minusone,@x)   '-x
    mpf_mul(@B,@x,@x) 'x*x
    If Mpf_cmp(@B,@one) = 0 Then
        'for 1 and -1  
        If mpf_cmp(@x,@minusone)=0 Then
            Dim As mpf_t four
            mpf_init(@four)
            mpf_init_set_str(@four,"4",10)
            mpf_mul(@four,@four,@atn1)
            Return four
        Else
            Dim As mpf_t zero
            mpf_init(@zero)
            mpf_init_set_str(@zero,"0",10)
            Return zero
        End If
    End If
    mpf_sub(@B,@one,@B)        '1-x*x
    mpf_sqrt(@B,@B)            'sqr(1-x*x)
    mpf_div(@term1,@T,@B)
    atnterm1=_ATN(term1)
    mpf_add(@ans,@atnterm1,@tail)
    Return ans
End Function
Function _Asin Overload(x As mpf_t) As mpf_t
    ' ARCSIN = ATN(x / SQR(-x * x + 1))
    '============= ARCSIN GUARD =========
    Var num= mpf_get_d(@x)
    If num>1 Then Exit Function
    If num<-1 Then Exit Function
    '========================
    Dim As mpf_t  one,T,B,term1,atnterm1,minusone
    mpf_init(@minusone)
    mpf_init(@one)
    mpf_init(@T)
    mpf_init(@B)
    mpf_init(@term1)
    mpf_init_set_str(@one,"1",10)
    mpf_init_set_str(@minusone,"-1",10)
    mpf_set(@T,@x)
    'T=x
    mpf_mul(@B,@x,@x)          'x*x
    'for 1 and -1
    If Mpf_cmp(@B,@one) = 0 Then
        Dim As mpf_t two,atn1
        mpf_init(@two)
        mpf_init_set_str(@two,"2",10)
        atn1=_atn(one)
        If mpf_cmp(@x,@minusone)=0 Then
            mpf_mul(@two,@two,@atn1)
            mpf_mul(@two,@two,@minusone)
            Return two
        Else
            mpf_mul(@two,@two,@atn1)
            Return two
        End If
    End If
    mpf_sub(@B,@one,@B)        '1-x*x
    mpf_sqrt(@B,@B)            'sqr(1-x*x)
    mpf_div(@term1,@T,@B)
    atnterm1=_ATN(term1)
    Return atnterm1
End Function


'===========================================================================
'=======================   OVERLOADS  FOR STRINGS ===============================
Dim Shared As Zstring * 100000000 outtext

Function Pi_ui Overload(places As Integer) As String
    Dim As Mpf_t ans
    Var pl=Cuint(places)
    ans=pi_ui(pl)
    gmp_sprintf( @outtext,"%." & pl & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _sin Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_sin(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _cos Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_cos(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _tan Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_tan(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _log Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_log(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _exp Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_exp(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function power Overload(a As String,p As String) As String
    Dim As Mpf_t _x,ans,pow
    mpf_init(@_x)
    mpf_init_set_str(@_x,a,10)
    mpf_init(@pow)
    mpf_init_set_str(@pow,p,10)
    ans=power(_x,pow)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _Atn Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_Atn(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _Acos Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_Acos(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function

Function _Asin Overload(x As String) As String
    Dim As Mpf_t _x,ans
    mpf_init(@_x)
    mpf_init_set_str(@_x,x,10)
    ans=_Asin(_x)
    gmp_sprintf( @outtext,"%." & precision & "Ff",@ans )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt) 
End Function


Function factorial(n As Uinteger) As String 'Automatic precision
    Dim As __mpz_struct Intanswer
    mpz_init2( @Intanswer,0)
    mpz_set_str( @Intanswer,"",10)
    mpz_fac_ui(@Intanswer,n)
    gmp_sprintf( @outtext,"%Zi", @Intanswer )
    Return Trim(outtext)
End Function

function _mod(n1 as string,n2 as string) as string
   dim as __mpz_struct answer,mn1,mn2
   mpz_init2( @answer,0)
    mpz_init2( @mn1,0)
     mpz_init2( @mn2,0)
   mpz_init_set_str( @answer,"",10)
   mpz_init_set_str( @mn1,n1,10)
   mpz_init_set_str( @mn2,n2,10)
   mpz_mod(@answer,@mn1,@mn2)
   gmp_sprintf( @outtext,"%Zi", @answer )
    Return Trim(outtext)
   
end function

Function Sqrroot(number As String,decimals As Uinteger=PRECISION) As String'precision parameter
    if instr(number,"-") then exit function
    Dim As __mpf_struct num,FloatAnswer
    Dim As Integer LN=Len(number)
    mpf_init2(@num,4*Ln):mpf_init2(@FloatAnswer,4*Ln)
    mpf_set_str(@num,number,10)
    mpf_sqrt( @FloatAnswer,@num)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer )
    Return Trim(outtext)
End Function

Function mult(number1 As String,number2 As String) As String'Automatic precision
    Dim As Integer Ln1=Len(number1),Ln2=Len(number2)
    Dim As __mpf_struct num1,num2,FloatAnswer
    mpf_init2( @num1,4*(Ln1+Ln2+1) )
    mpf_init2( @num2,4*(Ln1+Ln2+1) )
    mpf_init2(@Floatanswer,4*(Ln1+Ln2+1))
    Ln1=Instr(1,number1,"."):Ln2=Instr(1,number2,".")
    var decimals=Len(Mid(number1,Ln1+1))+Len(Mid(number2,Ln2+1))+1
    mpf_set_str( @num1,number1,10)
    mpf_set_str( @num2,number2,10)
    mpf_mul(@Floatanswer,@num1,@num2)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer )
    var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function

'precision parameter
Function divide(number1 As String,number2 As String,decimals As Uinteger=PRECISION) As String
    Dim As Integer Ln1=Len(number1),Ln2=Len(number2),Ln
    If Ln1>=Ln2 Then  Ln=Ln1 Else Ln=Ln2
    Dim As __mpf_struct num1,num2,FloatAnswer
    mpf_init2( @num1,4*(Ln+1) )
    mpf_init2( @num2,4*(Ln+1) )
    mpf_init2(@Floatanswer,4*(Ln+1)+4*decimals)
    mpf_set_str( @num1,number1,10)
    mpf_set_str( @num2,number2,10)
    mpf_div(@Floatanswer,@num1,@num2)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer)
    Return Trim(outtext)
End Function

Function  Power Overload(number As String,n As Uinteger) As String'automatic precision
    #define dp 3321921
    Dim As __mpf_struct _number,FloatAnswer
    Dim As Ulongint ln=Len(number)*(n)*4
    If ln>dp Then ln=dp
    mpf_init2(@FloatAnswer,ln)
    mpf_init2(@_number,ln) 'or 4*len(number)
    mpf_set_str(@_number,number,10)
    mpf_pow_ui(@Floatanswer,@_number,n)
    gmp_sprintf( @outtext,"%." & Str(n) & "Ff",@FloatAnswer )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function

Function plus(number1 As String,number2 As String) As String'automatic precision
    Dim As Integer Ln1=Len(number1),Ln2=Len(number2),decimals,Ln
    If Ln1>=Ln2 Then Ln=Ln1 Else Ln=Ln2
    Ln=ln+1
    Dim As __mpf_struct num1,num2,FloatAnswer
    mpf_init2( @num1,4*(Ln1+1) )
    mpf_init2( @num2,4*(Ln2+1) )
    mpf_init2(@Floatanswer,4*(Ln))
    mpf_set_str( @num1,number1,10)
    mpf_set_str( @num2,number2,10)
    Ln1=Instr(1,number1,"."):Ln2=Instr(1,number2,".")
    If Ln1 Or Ln2 Then
        decimals=Len(Mid(number1,Ln1+1))+Len(Mid(number2,Ln2+1))+1
    End If
    mpf_add(@Floatanswer,@num1,@num2)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer )
    var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function

Function minus(number1 As String,number2 As String) As String'automatic precision
    Dim As Integer Ln1=Len(number1),Ln2=Len(number2),decimals,Ln
    If Ln1>=Ln2 Then  Ln=Ln1 Else Ln=Ln2
    Ln=ln+1
    Dim As __mpf_struct num1,num2,FloatAnswer
    mpf_init2( @num1,4*(Ln1+1) )
    mpf_init2( @num2,4*(Ln2+1) )
    mpf_init2(@Floatanswer,4*(Ln))
    mpf_set_str( @num1,number1,10)
    mpf_set_str( @num2,number2,10)
    Ln1=Instr(1,number1,"."):Ln2=Instr(1,number2,".")
    If Ln1 Or Ln2 Then
        decimals=Len(Mid(number1,Ln1+1))+Len(Mid(number2,Ln2+1))+1
    End If
    mpf_sub(@Floatanswer,@num1,@num2)
    gmp_sprintf( @outtext,"%." & Str(decimals) & "Ff",@FloatAnswer )
    var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function
function Absolute overload(a As string) as  string
    Dim As __mpf_struct Ab,Floatanswer
     mpf_init2( @FloatAnswer,4*precision )
     mpf_init2( @Ab,4*precision )
     mpf_set_str( @Ab,a,10)
     mpf_abs(@FloatAnswer,@Ab)
     gmp_sprintf( @outtext,"%." & Str(precision) & "Ff",@FloatAnswer )
    var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
end function

function greater overload(a as string,b as string) as integer
   dim as mpf_t ma,mb
   mpf_init2(@ma,4*precision)
   mpf_init2(@mb,4*precision)
    mpf_set_str( @ma,a,10)
    mpf_set_str( @mb,b,10)
    return greater(ma,mb)
end function
function equals overload(a as string,b as string) as integer
       dim as mpf_t ma,mb
   mpf_init2(@ma,4*precision)
   mpf_init2(@mb,4*precision)
    mpf_set_str( @ma,a,10)
    mpf_set_str( @mb,b,10)
    return equals(ma,mb)
end function

function less overload(a as string,b as string) as integer
   if equals(a,b) then return 0
   if greater(a,b) then return 0
   return -1
    end function

'======================== TESTS ===============================
''Extern gmp_version Alias "__gmp_version" As Zstring Ptr
Print "GMP version ";*gmp_version
set_precision(2000)

Print "256.00098 ^ -6.003"
Print "press a key"
Sleep
Dim As String num="256.00098",pow="-6.003"
Print "power ";num;" to ";pow
Print power(num,pow)
Print "Float check"
Print Val(num)^Val(pow)
Print "Now pi to 5000 places"
Print "Press a key"
Sleep
Print
Print
Print "pi from Pi_ui"
Print Pi_ui(5000)
Print "Press a key"
Sleep
Print

Print
Print
Print "Log(50000.5)"
Print _log("50000.5")
Print
Print "Float check"
Print Str(Log(50000.5))
Print "Press a key"
Sleep
Print 


set_precision(60)
Print
Print "sin(.33)"
Print _sin(".33"),Sin(.33)
Print
Print "cos(-300.988)"
Print _cos("-300.988"),Cos(-300.988)
Print
Print "tan(1000000)"
Print _tan("1000000"),Tan(1000000)
Print
Print " Now -- 2 to power 1000000"
Print "press a key"
Sleep
Print
Print power("2",1000000)
Print
Print "now  1/5.870099330099900999 to 10000 places"
Print "press a key"
Sleep
var ans=divide("1","5.870099330099900999",10000)
Print ans
Print "Check length  ";Len(ans)
Print "e to 4000 places"
Print "press a key"
Sleep
set_precision(4000)
print _exp("1")

Print
Print "Last test, acos(-1), which is pi"
Print "press a key"
Sleep
Print _acos("-1")
Print "Done"
dim as string g="-56.99"
print absolute(g)

sleep
jdmcbride
Posts: 28
Joined: Aug 06, 2016 16:13

Re: gmp 6.1.0

Post by jdmcbride »

Hi,

I just found this discussion as I, like a lot of FB users, have discovered just how short floats and integers are in FreeBasic. I'll be posted a feature request for longer precision.

Until that time, this should hold me over, if I can figure out how to use it in my routines.

Thank you, very much for your love of FreeBasic.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: gmp 6.1.1 and mpfr 3.1.5

Post by srvaldez »

updated
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: gmp 6.1.1 and mpfr 3.1.5

Post by dodicat »

Thanks srvaldez.
I tested out the 64 bit library (with FreeBASIC'S gmp.bi), and the various functions, all OK.
FreeFox
Posts: 69
Joined: Sep 28, 2016 23:45

Re: gmp 6.1.1 and mpfr 3.1.5

Post by FreeFox »

@srvaldez

Thanks for posting links to the binaries for these incredibly fast libraries which has probably saved me a lot of hassle trying to get them to work with Windows ;)
frisian
Posts: 249
Joined: Oct 08, 2009 17:25

Re: gmp 6.1.1 and mpfr 3.1.5

Post by frisian »

@srvaldez

Both links (GMP/MPRF) do not work, in both cases I get
Invalid or Deleted File.

The key you provided for file access was invalid. This is usually caused because the file is no longer stored on MediaFire. This occurs when the file is removed by the originating user or MediaFire.

Still have questions, or think we've made a mistake? Please contact support for further assistance.
.
integer
Posts: 408
Joined: Feb 01, 2007 16:54
Location: usa

Re: gmp 6.1.1 and mpfr 3.1.5

Post by integer »

srvaldez wrote:here are the binaries for gmp-6.1.1
and mpfr-3.1.5
for anyone interested
MediaFire
Invalid or Deleted File.
The key you provided for file access was invalid.
This is usually caused because the file is no longer stored on MediaFire.
This occurs when the file is removed by the originating user or MediaFire.

©2016 MediaFire Build 117651 ...
@srvaldez
You updated this on Nov.29 (Thank you very much.)
Are the file available somewhere else?
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: gmp 6.1.1 and mpfr 3.1.5

Post by srvaldez »

hello frisian and integer
links updated
frisian
Posts: 249
Joined: Oct 08, 2009 17:25

Re: gmp 6.1.1 and mpfr 3.1.5

Post by frisian »

srvaldez wrote:hello frisian and integer
links updated
Thanks
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: gmp 6.1.2 and mpfr 3.1.5

Post by srvaldez »

updated
Post Reply