Values

General FreeBASIC programming questions.
Post Reply
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Values

Post by albert »

Dear Coders;

Can you guys put into FB a thing to convert base 256 to integer values?

Call it "&A" , for ASCII

DIM AS ULONGINT number = VAL( "&A" + (base256 string) ) , up to 8 bytes..

Currently you have to break the string into bytes and convert them to RIGHT( BIN ( ASC( byte ) ) , 8)
And then do a VAL( "&B" + (bin string) + (bin string) + etc.. )
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Values

Post by counting_pine »

Here's a fairly simple routine you can use:

Code: Select all

function vallng_256(s as string) as longint
    dim ret as ulongint = 0
    for i as integer = 0 to len(s)-1
        ret = ret shl 8 or s[i]
    next i
    return ret
end function

print hex(vallng_256("ABCDEFGH")) '' 4142434445464748
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Values

Post by albert »

@counting_pine

How do you get it to convert strings longer than 8 bytes?
I want to convert a file into base 10 decimal..

maybe i should just step by 8 bytes...
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Values

Post by dodicat »

Hi Albert.
You can do it this way:

Code: Select all

'look up tables for speed
Dim Shared ADDQmod(0 To 19) As Ubyte
Dim Shared ADDbool(0 To 19) As Ubyte
For z As Integer=0 To 19
    ADDQmod(z)=(z Mod 10+48)
    ADDbool(z)=(-(10<=z))
Next z 
Dim shared As integer _Mod(0 To 99),_Div(0 To 99)
For z As Integer=0 To 99:_Mod(z)=(z Mod 10+48):_Div(z)=z\10:next
  '================      
function Qmult(a as string,b as string) as string
      var flag=0,la = len(a),lb = len(b)
      If Len(b)>Len(a) Then flag=1:swap a,b:swap la,lb
dim as ubyte n,carry,ai
    var c =string(la+lb,"0")
    for i as integer =la-1 to 0 step -1
        carry=0:ai=a[i]-48
        for j as integer =lb-1 to 0 step -1
			 n = ai * (b[j]-48) + (c[i+j+1]-48) + carry
              carry =_Div(n):c[i+j+1]=_Mod(n)
            next j
        c[i]+=carry
    next i
 if flag then swap a,b
	return ltrim(c,"0")
end function
Function plus(_num1 As String,_num2 As String) As String
    var _flag=0,n_=0
    Dim As Ubyte addup=Any,addcarry=Any
    #macro finish()
    answer=Ltrim(answer,"0")
    If _flag=1 Then Swap _num2,_num1
    Return answer
    #endmacro
    If Len(_num2)>Len(_num1) Then 
        Swap _num2,_num1
        _flag=1
        Endif
        var diff=Len(_num1)-Len(_num2)
        var answer="0"+_num1
        addcarry=0
        For n_=Len(_num1)-1 To diff Step -1 
            addup=_num2[n_-diff]+_num1[n_]-96
            answer[n_+1]=ADDQmod(addup+addcarry)
            addcarry=ADDbool(addup+addcarry)
        Next n_ 
        If addcarry=0 Then 
            finish()
        End If
        If n_=-1 Then 
            answer[0]=addcarry+48
            finish()
            Endif
            For n_=n_ To 0 Step -1 
                addup=_num1[n_]-48
                answer[n_+1]=ADDQmod(addup+addcarry)
                addcarry=ADDbool(addup+addcarry)
                If addcarry=0 Then Exit For
            Next n_
            answer[0]=addcarry+48
            finish()
        End Function
        ' ============== BINARY TO DECIMAL =================================     
        Function convertto10(Base256Number As String,b as string="256") As String
            Dim As String sum
            sum=Str(Asc(Left(Base256Number,1)))
            For n As Integer=2 To Len(Base256Number)
                sum=plus(Qmult(sum,b),Str((Base256Number[n-1])) ) 
            Next n
            Return sum
        End Function
        
        
        
    function vallng_256(s as string) as longint  'Counting Pine
    dim ret as ulongint = 0
    for i as integer = 0 to len(s)-1
        ret = ret shl 8 or s[i]
    next i
    return ret
end function

print vallng_256("ABCDEFGH"), "counting pine method"

print convertto10("ABCDEFGH"), "dodicat method"
print
print convertto10("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),"dodicat method"

sleep
         
It is faster with gmp.
Are you using windows again?
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Values

Post by albert »

@Dodicat

That works , thank you!!

How do you reverse it , and convert it back to base 256??
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Values

Post by dodicat »

Hi Albert.
If you have the gmp library then:

Code: Select all


#Include once "gmp.bi"
'from a base 10 number to a base b (default 256)
Function converttobase(Byval Base10 As String ,b As String="256",begin As Long=0) As String
    Dim As zstring Ptr s
    Dim As __mpz_struct answer,id,divd,modd,bb,zero
    mpz_init2( @answer,0)
    mpz_init2( @id,0)
    mpz_init2( @divd,0)
    mpz_init2( @modd,0)
    mpz_init2( @bb,0)
    mpz_init2( @zero,0)
    mpz_init_set_str( @id,Base10,10)
    mpz_init_set_str( @bb,b,10)
    Dim As String acc
    Do
        mpz_div(@divd,@id,@bb)
        mpz_mod(@modd,@id,@bb)
        s= mpz_get_str(0, 10, @modd)
        acc= Chr(Vallng(*s)+begin)+acc
        Mpz_set(@id,@divd)
    Loop Until  Mpz_cmp(@divd,@zero)=0 
    Function= acc
    mpz_clear(@answer) : mpz_clear(@id) : mpz_clear(@divd)
    mpz_clear(@modd) : mpz_clear(@bb) : mpz_clear(@zero)
    Deallocate s
End Function

'from a base b default 256 to a base 10 number
Function convertbaseto10(Byval Basenum As String ,b As String="256",begin As Long=0) As String
    Dim As zstring Ptr s
    Dim As String sum
    Dim As Ulong u=Valulng(b)
    sum=Str(Asc(Left(BaseNum,1))-begin)
    Dim As __mpz_struct mul,znum,zsum
    mpz_init2( @mul,0)
    mpz_init2 (@znum,0)
    mpz_init2 (@zsum,0)
    mpz_set_str(@zsum,sum,10)
    For n As Long=2 To Len(basenum)
        Var z=basenum[n-1]
        mpz_mul_ui(@mul,@zsum,u)
        mpz_set_str(@znum,Str(z-begin),10)
        mpz_add(@zsum,@mul,@znum)
    Next n
    s= mpz_get_str(0, 10, @zsum) 
    Function= *s
    mpz_clear(@mul) : mpz_clear(@znum) : mpz_clear(@zsum)
    Deallocate s
    
End Function  
gmp seems the fastest way.
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Values

Post by albert »

@Dodicat

Where do you get the gmp libs ?? and gmp.bi ??
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Values

Post by dodicat »

GMP.
srvaldez posted them a while back.
I put them here on mediafire
http://www.mediafire.com/file/6hj8ry1jj ... -6.1.1.zip

The gmp.bi supplied from freebasic is OK here, but srvaldez has supplied others I see.
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Values

Post by albert »

@Dodicat

Hi , Dodicat, i've been down a few days with the flu..

I just reinstalled Linux..I keep getting hacked..
Got the GMP libs and stuck them in the FB folders and its working..

Thanks !!
Post Reply