Squares

General FreeBASIC programming questions.
Locked
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Post by Richard »

@Albert. Why do you insist on doing the impossible backwards?

The fundamental of logic is the Complement or NOT function. It can be done by one transistor and one input resistor. The fundamental two input AND and OR functions can be made simply using one diode for each input. By using a transistor to invert the signals gets you NAND and NOR.

There is no quick way to do MOD using electronic components. MOD is way too complicated and slow to use for making bitwise logic functions. To do MOD you must be first able to subtract which is more difficult than doing addition, or bitwise logic. So you must start construction of a calculator from the basis of having only the electronic bitwise gates = NOT, AND, OR, shift and a register to remember the bits.

From those you can next build XOR, ADD, SUB, then MUL, DIV and MOD.

Code: Select all

'=======================================================================
' Arithmetic addition by logic using only Not AND.
'=======================================================================
Function Nand(Byval a As Ulong, Byval b As Ulong) As Ulong
    Nand = Not( a And b )
End Function

'-----------------------------------------------------------------------
Function Exor(Byval a As Ulong, Byval b As Ulong) As Ulong
    Dim As Ulong c = Nand( a, b )
    Return Nand( Nand( a, c ), Nand( b, c ) )
End Function

'-----------------------------------------------------------------------
Function Sum(Byval a As Ulong, Byval b As Ulong) As Ulong
    Dim As Ulong c
    Do
        c = ( a And b ) Shl 1   ' carry
        a = Exor( a, b )        ' sum
        b = c
    Loop While c
    Return a
End Function

'=======================================================================
Randomize
Dim As Ulong a, b
' Do
    a = Rnd * 1024
    b = Rnd * 1024
' Loop While Sum( a, b ) = a + b
Print a, b, Sum( a, b ), a + b

'=======================================================================
Sleep

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

Re: Squares

Post by dodicat »

Using only not and and for add.

Code: Select all



Function Add(a As Ulongint,b As Ulongint) As Ulongint
    If a Then Add= Add((a And b) Shl 1, (Not(a And b)) And (Not(Not a And Not b))) Else Add= b
End Function


redim as ulongint a(1 to 10000000)
redim as ulongint b(1 to 10000000)
For n As Long=1 To 10000000
    a(n)=Culngint(9223372036854775806ull +Culngint(Rnd*1000))
    b(n)=Culngint(922337203685477ull     +Culngint(Rnd*1000))
Next



Dim As ulongint c
For n As Long=1 To 10000000
    If a(n) + b(n) <> Add(a(n),b(n)) Then Print "Error"
Next
Print "Test complete"
Dim As Double t

t=Timer
For n As Long=1 To 10000000
    c=a(n)+b(n)
Next

Print Timer-t,c

sleep 50
t=Timer
For n As Long=1 To 10000000
    
    c=Add(a(n),b(n))
Next
Print Timer-t,c

Print "Done"
Sleep

  
quite slow of course.
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Post by albert »

@Richard

I'm trying to write faster logic functions , I wrote a faster MOD = ( a - ( ( a \ b ) *b ) )

I'm trying to write all the logic functions using only + - \ / , mod , shl , shr....or one our your created logic functions..

If you write and AND function , then you can use that function to solve other logic functions.
If you write and XOR function , then you can use that function to solve other logic functions.
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Post by albert »

@Richard
@Dodicat

I got my XOR and AND working , with 1 and powers of 2...

a = int( rnd * 1e10 )
b = 2 ^ ??

Code: Select all


screen 19

dim as double time1 , time2

dim as double builtin_xor_low = 1
dim as double builtin_and_low = 1

dim as double Albert_xor_low  = 1
dim as double Albert_and_low  = 1

dim as longint builtin_xor
dim as longint builtin_and

dim as longint Albert_xor
dim as longint Albert_and

dim as ulongint a , b
dim as longint loops = 0

do
    loops = 0
    
    builtin_xor_low = 1
    builtin_and_low = 1
    
    Albert_xor_low  = 1
    Albert_and_low  = 1

do
    
    loops +=1

    a = rnd * 1e10
    b = 2 ^ int( rnd *32 )
    
    dim as longint md = b+b
    
    time1 = timer
        for x as longint = 1 to 1e6
            builtin_xor =  a xor b
        next
    time2 = timer
    if time2 - time1 < builtin_xor_low then builtin_xor_low = time2-time1

    time1 = timer
        for x as longint = 1 to 1e6
            builtin_and =  a and b
        next
    time2 = timer
    if time2 - time1 < builtin_and_low then builtin_and_low = time2-time1


    'Alberts XOR formula  ( works for 1 and all powers of 2 )
    time1 = timer
        dim as ulongint plus = a+b
        dim as ulongint minus = a-b 
        for x as longint = 1 to 1e6
            'Albert_xor = ( a mod (b+b) ) + -b
            Albert_xor =  a - ( ( a \ md ) * md )   ' Albert_MOD formula   
            if b > Albert_xor then Albert_xor = plus else Albert_xor = minus
        next
    time2 = timer
    if time2 - time1 < Albert_xor_low   then Albert_xor_low  = time2-time1
   
    'Alberts AND formula  ( works for 1 and all powers of 2 )
    time1 = timer
        plus = 0
        minus = b
        for x as longint = 1 to 1e6
            'Albert_and = ( a mod (b+b) ) + -b
            Albert_and =  a - ( ( a \ md ) * md )   ' Albert_MOD formula   
            if b > Albert_and then Albert_and = plus else Albert_and = minus
        next
    time2 = timer
    if time2 - time1 < Albert_and_low   then Albert_and_low  = time2 - time1

    dim as longint diff_xor = builtin_xor - Albert_xor
    dim as longint diff_and = builtin_and - Albert_and
        
    print
    print "a = " ; a ; " b = " ; b
    print
    print "builtin Xor = "  ; builtin_xor
    print "Albert Xor  = "  ; Albert_xor
    print
    print "builtin And = "  ; builtin_and
    print "Albert And  = "  ; Albert_and
    
    if diff_xor <> 0 then print "XOR ERROR" : sleep
    if diff_and <> 0 then print "AND ERROR" : sleep
    
    
    print loops ; " out of  " ; 500

    if inkey = " " then sleep
    if inkey = chr(27) then end
    
loop until loops = 500
    
    cls
    print
    print "a = " ; a ; " b = " ; b
    print
    print "builtin Xor = "  ; builtin_xor , builtin_xor_low
    print "Albert Xor  = "  ; Albert_xor , Albert_xor_low
    print
    print "builtin And = "  ; builtin_and , builtin_and_low
    print "Albert And  = "  ; Albert_and , Albert_and_low
    
    sleep
    
loop until inkey= chr(27)

sleep
end



Now to do numbers outside of powers of 2
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Post by Richard »

Albert wrote:Now to do numbers outside of powers of 2
You need to avoid the Mod function and start from the most primitive operators. They are NOT, AND and OR.
You can then make XOR( a, b ) = ( a And Not(b) ) Or ( b And Not(a) ) from which you can do addition.
Once you can ADD you can INCrement which makes it possible to do two's complement negation and subtraction of all binary numbers.
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Post by albert »

Hi Richard!!

I'm not trying to write all the functions , just the logic functions..
For the logic functions , you can use ( add , sub , mul , div , shr , shl , mod ) ( mod ; since i wrote a mod function.)

Here's Xor and And , doing powers of 2:

Code: Select all


screen 19

dim as double  time1 , time2
dim as double  time3 , time4
dim as double  time5 , time6
dim as double  time7 , time8

dim as double builtin_xor_low = 1
dim as double builtin_and_low = 1

dim as double Albert_xor_low  = 1
dim as double Albert_and_low  = 1

dim as longint builtin_xor
dim as longint builtin_and

dim as longint Albert_xor
dim as longint Albert_and

dim as ulongint a , b
dim as longint loops = 0

do
    loops = 0
    
    builtin_xor_low = 1
    builtin_and_low = 1
    
    Albert_xor_low  = 1
    Albert_and_low  = 1

do
    
    loops +=1

'===================================
    a = rnd * 1e10
    b = 2 ^ int( rnd *32 )
'=================================== 

    dim as longint md = b+b
    
    time1 = timer
        for x as longint = 1 to 1e7
            builtin_xor =  a xor b
        next
    time2 = timer
    if time2 - time1 < builtin_xor_low then builtin_xor_low = time2 - time1

    time3 = timer
        for x as longint = 1 to 1e7
            builtin_and =  a and b
        next
    time4 = timer
    if time4 - time3 < builtin_and_low then builtin_and_low = time4 - time3


    'Alberts XOR formula  ( works for 1 and all powers of 2 )
    time5 = timer
        dim as ulongint plus = a+b
        dim as ulongint minus = a-b 
        for x as longint = 1 to 1e7
            'Albert_xor = ( a mod (b+b) ) + -b
            Albert_xor =  a - ( ( a \ md ) * md )   ' Albert_MOD formula   
            if b > Albert_xor then Albert_xor = plus else Albert_xor = minus
        next
    time6 = timer
    if time6 - time5 < Albert_xor_low   then Albert_xor_low  = time6 - time5
   
    'Alberts AND formula  ( works for 1 and all powers of 2 )
    time7 = timer
        for x as longint = 1 to 1e7
            'Albert_and = ( a mod (b+b) ) + -b
            Albert_and =  a - ( ( a \ md ) * md )   ' Albert_MOD formula   
            if b > Albert_and then Albert_and = 0 else Albert_and = b
        next
    time8 = timer
    if time8 - time7 < Albert_and_low   then Albert_and_low  = time8 - time7

    dim as longint diff_xor = builtin_xor - Albert_xor
    dim as longint diff_and = builtin_and - Albert_and
        
    print
    print "a = " ; a ; " b = " ; b
    print
    print "builtin Xor = "  ; builtin_xor , time2 - time1
    print "Albert Xor  = "  ; Albert_xor , time6 - time5
    print
    print "builtin And = "  ; builtin_and , time4 - time3
    print "Albert And  = "  ; Albert_and , time8 - time7
    
    if diff_xor <> 0 then print "XOR ERROR" : sleep
    if diff_and <> 0 then print "AND ERROR" : sleep
    
    
    print loops ; " out of  " ; 500

    if inkey = " " then sleep
    if inkey = chr(27) then end
    
loop until loops = 500
    
    cls
    print
    print "a = " ; a ; " b = " ; b
    print
    print "builtin Xor = "  ; builtin_xor , builtin_xor_low / 1e7
    print "Albert Xor  = "  ; Albert_xor  , Albert_xor_low  / 1e7
    print
    print "builtin And = "  ; builtin_and , builtin_and_low / 1e7
    print "Albert And  = "  ; Albert_and  , Albert_and_low  / 1e7
    
    sleep
    
loop until inkey= chr(27)

sleep
end

badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Squares

Post by badidea »

First post of the topic:
Richard wrote:... So why not post your silly code here. ...
Seems to be on-topic still :-)
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Post by Richard »

Code: Select all

' Bitwise Logic Functions,  NOT, AND, OR, XOR, by arithmetic without using those logic functions
'-------------------------------------------------------
Function arith_NOT( Byval x As Ubyte ) As Ubyte
    Return 255 - x
End Function

'-------------------------------------------------------
Function arith_AND( Byval x As Ubyte, Byval y As Ubyte ) As Ubyte
    Dim As Ubyte temp = 0, pit = 1
    For i As Integer = 0 To 7
        If x <> ( x Shr 1 ) Shl 1 Then
            If y <> ( y Shr 1 ) Shl 1 Then temp = temp + pit
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function

'-------------------------------------------------------
Function arith_OR( Byval x As Ubyte, Byval y As Ubyte ) As Ubyte
    Dim As Ubyte temp = 0, pit = 1, flag
    For i As Integer = 0 To 7
        If x <> ( x Shr 1 ) Shl 1 Then flag = 1
        If y <> ( y Shr 1 ) Shl 1 Then flag = 1
        If flag Then 
            temp = temp + pit
            flag = 0
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function

'-------------------------------------------------------
Function arith_XOR( Byval x As Ubyte, Byval y As Ubyte ) As Ubyte
    Dim As Ubyte temp = 0, pit = 1, flag = 0
    For i As Integer = 0 To 7
        If x <> ( x Shr 1 ) Shl 1 Then flag = 1
        If y <> ( y Shr 1 ) Shl 1 Then flag = 1 - flag
        If flag Then 
            temp = temp + pit
            flag = 0
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

AND 5

Post by albert »

@Richard

Thanks for the code!!

Here's my attempt at n1 AND 5.. I'm getting the first 1 and 0 , and the 4 5..

Code: Select all



screen 19

print "a" , " b" , " a and b" , "Albert and"

for a as longint = 1 to 20 step 1 
    
    dim  as longint  b = 5 
    
    dim as longint b_a = a and b 
    
    dim as longint a_a =  (4 - ((a + b) mod 2 - 1 mod 2 ) ) mod (2 ^ a)
    
        'b = 1 and all powers of 2
            'Albert_and =  a - ( ( a \ md ) * md )   ' Albert_MOD formula   
            'if b > Albert_and then Albert_and = 0 else Albert_and = b
        
        'b = 3
            'Albert_and =   a mod( 2 ^ 2 )
    
    print a , b ,  b_a ,  a_a
    
next

sleep
end

albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Richard Logic Functions

Post by albert »

@Richard

Hi , Richard....

I played around with your logic functions , and converted ubyte to ulongint. They all work good....with ulongint

Code: Select all


screen 19


' Bitwise Logic Functions,  NOT, AND, OR, XOR, by arithmetic without using those logic functions
'-------------------------------------------------------
Function arith_NOT( Byval x As ulongint ) As ulongint
    Return  - x-1
End Function

'-------------------------------------------------------
Function arith_AND( Byval x As ulongint , Byval y As ulongint  ) As ulongint 
    Dim As ulongint  temp = 0, pit = 1
    For i As Integer = 0 To 63
        If x <> ( x Shr 1 ) Shl 1 Then
            If y <> ( y Shr 1 ) Shl 1 Then temp = temp + pit
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function

'-------------------------------------------------------
Function arith_OR( Byval x As ulongint , Byval y As ulongint  ) As ulongint 
    Dim As ulongint  temp = 0, pit = 1, flag
    For i As Integer = 0 To 63
        If x <> ( x Shr 1 ) Shl 1 Then flag = 1
        If y <> ( y Shr 1 ) Shl 1 Then flag = 1
        If flag Then
            temp = temp + pit
            flag = 0
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function

'-------------------------------------------------------
Function arith_XOR( Byval x As ulongint , Byval y As ulongint  ) As ulongint 
    Dim As ulongint  temp = 0, pit = 1, flag = 0
    For i As Integer = 0 To 63
        If x <> ( x Shr 1 ) Shl 1 Then flag = 1
        If y <> ( y Shr 1 ) Shl 1 Then flag = 1 - flag
        If flag Then
            temp = temp + pit
            flag = 0
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function

'================================================================
'================================================================
'test functions
'================================================================
'================================================================

randomize
do
    
    dim as ulongint  n1 = int( rnd*1e10)
    dim as ulongint  n2 = int( rnd*1e10)
    
    print "============================================"
    print
    print "n1 = " ; n1
    print "n2 = " ; n2
    print
    print "Builtin NOT = "; not n1
    print "Richard NOT = " ; arith_NOT( n1 )
    print
    print "Builtin AND = " ; n1 and n2
    print "Richard AND = "; arith_AND( n1 , n2 )
    print
    print "Builtin OR  = " ; n1 or n2
    print "Richard OR  = " ; arith_OR( n1 , n2)
    print
    print "Builtin XOR  = " ; n1 xor n2
    print "Richard XOR  = ";  arith_XOR(n1 , n2)
    
    sleep

loop until inkey = chr(27)

sleep
end

Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Post by Richard »

@Albert.
I quickly wrote and posted the arithmetic logic functions before driving all day. By the time I got back I'd thought about what I was doing and so could write them differently. I really can't think of any use for them, apart from filling time.

I would have thought you would prohibit the use of IF THEN ELSE, along with logical SHL and SHR.
Here are the NOT, AND, OR and XOR, using only ADD, SUB, MUL and DIV. No need for SHL, SHR, MOD, IFs or BUTs.

They will use any integer data type for the logical variable. Define Ltype first.

Code: Select all

'=======================================================================
' Backward logic, boolean from arithmetic 
'=======================================================================
' "I'm not trying to write all the functions , just the logic functions" ... Albert
' Rules; for the logic functions , you can use ( add , sub , mul , div , shr , shl , mod )
'=======================================================================

#Define Ltype Ubyte ' identify the data type used for bitwise logical variables

'-------------------------------------------------------
' the odd arithmetic helper function
' Function odd( Byval x As Ltype ) As Ltype
'     Return x - 2 * ( x \ 2 )    ' do not optimise by cancellation of 2 
' End Function
#Define odd( x ) ((x) - 2 * ( (x) \ 2 ))

'-------------------------------------------------------
Function arith_NOT( Byval x As Ltype ) As Ltype
    Return &hFFFFFFFFFFFFFFFFull - x
End Function

'-------------------------------------------------------
Function arith_AND( Byval x As Ltype, Byval y As Ltype ) As Ltype
    Dim As Ltype t = 0, z = 1
    Do
        t += z * odd( x ) * odd( y )
        x \= 2
        y \= 2
        z *= 2
    Loop While z
    Return t
End Function

'-------------------------------------------------------
Function arith_OR( Byval x As Ltype, Byval y As Ltype ) As Ltype
    Dim As Ltype t = 0, z = 1
    Do
        t += z * ( 1 - ( ( 1 - odd( x ) ) * ( 1 - odd( y ) ) ) )
        x \= 2
        y \= 2
        z *= 2
    Loop While z
    Return t
End Function

'-------------------------------------------------------
Function arith_XOR( Byval x As Ltype, Byval y As Ltype ) As Ltype
    Dim As Ltype t = 0, z = 1
    Do
        t += z * odd( odd( x ) + odd( y ) )
        x \= 2
        y \= 2
        z *= 2
    Loop While z
    Return t
End Function

'-------------------------------------------------------
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Richard Logic Functions

Post by albert »

@Richard

I fiddled around and got timings for your two sets of logic functions..

( Richard Logic 1 )

Code: Select all

'
' Bitwise Logic Functions,  NOT, AND, OR, XOR, by arithmetic without using those logic functions
'-------------------------------------------------------
Function arith_NOT( Byval x As ulongint ) As ulongint
    Return  - x-1
End Function

'-------------------------------------------------------
Function arith_AND( Byval x As ulongint , Byval y As ulongint  ) As ulongint
    Dim As ulongint  temp = 0, pit = 1
    For i As Integer = 0 To 63
        If x <> ( x Shr 1 ) Shl 1 Then
            If y <> ( y Shr 1 ) Shl 1 Then temp = temp + pit
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function

'-------------------------------------------------------
Function arith_OR( Byval x As ulongint , Byval y As ulongint  ) As ulongint
    Dim As ulongint  temp = 0, pit = 1, flag
    For i As Integer = 0 To 63
        If x <> ( x Shr 1 ) Shl 1 Then flag = 1
        If y <> ( y Shr 1 ) Shl 1 Then flag = 1
        If flag Then
            temp = temp + pit
            flag = 0
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function

'-------------------------------------------------------
Function arith_XOR( Byval x As ulongint , Byval y As ulongint  ) As ulongint
    Dim As ulongint  temp = 0, pit = 1, flag = 0
    For i As Integer = 0 To 63
        If x <> ( x Shr 1 ) Shl 1 Then flag = 1
        If y <> ( y Shr 1 ) Shl 1 Then flag = 1 - flag
        If flag Then
            temp = temp + pit
            flag = 0
        End If
        pit = pit + pit
        x = x Shr 1
        y = y Shr 1
    Next i
    Return temp
End Function
'================================================================
'================================================================
'test functions
'================================================================
'================================================================
screen 19
randomize

dim as double time1 , time2

dim as double b_not   , r_not
dim as double b_and , r_and
dim as double b_or    , r_or
dim as double b_xor  , r_xor

do
    
dim as ulongint  n1 = int( rnd*1e10)
dim as ulongint  n2 = int( rnd*1e10)

dim as ulongint ans

cls

'built in functions , time for loops 1e6
    time1 = timer
        for x as longint = 1 to 1e6
            ans = not n1
        next
    time2 = timer
    b_not = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = n1 and n2
        next
    time2 = timer
    b_and = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = n1 or n2
        next
    time2 = timer
    b_or = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = n1 xor n2
        next
    time2 = timer
    b_xor = time2 - time1

'Richrd functions , time for loops 1e6
    time1 = timer
        for x as longint = 1 to 1e6
            ans = arith_not( n1 )
        next
    time2 = timer
    r_not = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = arith_and( n1 , n2)
        next
    time2 = timer
    r_and = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = arith_or( n1 , n2)
        next
    time2 = timer
    r_or = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = arith_xor( n1 , n2 )
        next
    time2 = timer
    r_xor = time2 - time1

    print "================================================="
    print "Builtin NOT time , 1e6 loops = " ; b_not
    print "Richard NOT time , 1e6 loops = " ; r_not
    print
    print "Builtin AND time , 1e6 loops = " ; b_and
    print "Richard AND time , 1e6 loops = " ; r_and
    print
    print "Builtin OR time , 1e6 loops  = " ; b_or
    print "Richard OR time , 1e6 loops  = " ; r_or
    print
    print "Builtin XOR time , 1e6 loops = " ; b_xor
    print "Richard XOR time , 1e6 loops = " ; r_xor
    print "================================================="

    print
    print "n1 = " ; n1
    print "n2 = " ; n2
    print
    print "Builtin NOT = "; not n1
    print "Richard NOT = " ; arith_NOT( n1 )
    print
    print "Builtin AND = " ; n1 and n2
    print "Richard AND = "; arith_AND( n1 , n2 )
    print
    print "Builtin OR  = " ; n1 or n2
    print "Richard OR  = " ; arith_OR( n1 , n2)
    print
    print "Builtin XOR  = " ; n1 xor n2
    print "Richard XOR  = ";  arith_XOR(n1 , n2)
   
    sleep

loop until inkey = chr(27)

sleep
end

( Richard Logic 2 )

Code: Select all


'=======================================================================
' Backward logic, boolean from arithmetic
'=======================================================================
' "I'm not trying to write all the functions , just the logic functions" ... Albert
' Rules; for the logic functions , you can use ( add , sub , mul , div , shr , shl , mod )
'=======================================================================

#Define Ltype ulongint ' identify the data type used for bitwise logical variables

'-------------------------------------------------------
' the odd arithmetic helper function
' Function odd( Byval x As Ltype ) As Ltype
'     Return x - 2 * ( x \ 2 )    ' do not optimise by cancellation of 2
' End Function
#Define odd( x ) ( (x) - 2 * ( (x) \ 2 ) )

'-------------------------------------------------------
Function arith_NOT( Byval x As Ltype ) As Ltype
    Return &hFFFFFFFFFFFFFFFFull - x
End Function

'-------------------------------------------------------
Function arith_AND( Byval x As Ltype, Byval y As Ltype ) As Ltype
    Dim As Ltype t = 0, z = 1
    Do
        t += z * odd( x ) * odd( y )
        x \= 2
        y \= 2
        z *= 2
    Loop While z
    Return t
End Function

'-------------------------------------------------------
Function arith_OR( Byval x As Ltype, Byval y As Ltype ) As Ltype
    Dim As Ltype t = 0, z = 1
    Do
        t += z * ( 1 - ( ( 1 - odd( x ) ) * ( 1 - odd( y ) ) ) )
        x \= 2
        y \= 2
        z *= 2
    Loop While z
    Return t
End Function

'-------------------------------------------------------
Function arith_XOR( Byval x As Ltype, Byval y As Ltype ) As Ltype
    Dim As Ltype t = 0, z = 1
    Do
        t += z * odd( odd( x ) + odd( y ) )
        x \= 2
        y \= 2
        z *= 2
    Loop While z
    Return t
End Function
'-------------------------------------------------------

'================================================================
'================================================================
'test functions
'================================================================
'================================================================
screen 19
randomize

dim as double time1 , time2

dim as double b_not   , r_not
dim as double b_and , r_and
dim as double b_or    , r_or
dim as double b_xor  , r_xor

do
    
dim as ulongint  n1 = int( rnd*1e10)
dim as ulongint  n2 = int( rnd*1e10)

dim as ulongint ans

cls

'built in functions , time for loops 1e6
    time1 = timer
        for x as longint = 1 to 1e6
            ans = not n1
        next
    time2 = timer
    b_not = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = n1 and n2
        next
    time2 = timer
    b_and = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = n1 or n2
        next
    time2 = timer
    b_or = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = n1 xor n2
        next
    time2 = timer
    b_xor = time2 - time1

'Richrd functions , time for loops 1e6
    time1 = timer
        for x as longint = 1 to 1e6
            ans = arith_not( n1 )
        next
    time2 = timer
    r_not = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = arith_and( n1 , n2)
        next
    time2 = timer
    r_and = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = arith_or( n1 , n2)
        next
    time2 = timer
    r_or = time2 - time1

    time1 = timer
        for x as longint = 1 to 1e6
            ans = arith_xor( n1 , n2 )
        next
    time2 = timer
    r_xor = time2 - time1

    print "================================================="
    print "Builtin NOT time , 1e6 loops = " ; b_not
    print "Richard NOT time , 1e6 loops = " ; r_not
    print
    print "Builtin AND time , 1e6 loops = " ; b_and
    print "Richard AND time , 1e6 loops = " ; r_and
    print
    print "Builtin OR time , 1e6 loops  = " ; b_or
    print "Richard OR time , 1e6 loops  = " ; r_or
    print
    print "Builtin XOR time , 1e6 loops = " ; b_xor
    print "Richard XOR time , 1e6 loops = " ; r_xor
    print "================================================="

    print
    print "n1 = " ; n1
    print "n2 = " ; n2
    print
    print "Builtin NOT = "; not n1
    print "Richard NOT = " ; arith_NOT( n1 )
    print
    print "Builtin AND = " ; n1 and n2
    print "Richard AND = "; arith_AND( n1 , n2 )
    print
    print "Builtin OR  = " ; n1 or n2
    print "Richard OR  = " ; arith_OR( n1 , n2)
    print
    print "Builtin XOR  = " ; n1 xor n2
    print "Richard XOR  = ";  arith_XOR(n1 , n2)
   
    sleep

loop until inkey = chr(27)

sleep
end

On my Linux System
With Geany IDE , build command fbc.exe -gen GCC -W all - O 3 , they both , come out to the same times as the builtin functions..

6.000?? e-007

I have an AMD quad core 2GHz processor with , OS = Ubuntu Linux 18.04 LTS 64 bit..
Richard
Posts: 3096
Joined: Jan 15, 2007 20:44
Location: Australia

Re: Squares

Post by Richard »

@Albert.
My code is significantly slower than the built-in logic functions. There must be a problem with the way you are applying your speed testing code.

I wrote the arithmetic logic functions to show that it is possible to “advance backwards” even faster, without using the MOD function.
Speed has no real relevance where the code should certainly never be seriously used.

It is now time for you to write an adder using the built-in logic functions only.
albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Post by albert »

@Richard
@Dodicat

I did a string "AND" , looping 1e6 times , it's about 100 times slower than the builtin AND..
But looping just once , its less than 10 times slower.

Code: Select all


screen 19

'====================================================
'====================================================
function Albert_and( a as string , b as string ) as string
    
    dim as longint y = len(a) - 1
    dim as longint x = len(b) - 1
    do
        b[x] = ( b[x] + a[y] ) \ 2
        x-= 1
        y-= 1
    loop until x = -1
    
    return b

end function
'====================================================
'====================================================

randomize

do
    
        dim as ulongint a = int( rnd*1e10 )
        dim as ulongint b = int( rnd*1e10 )
        
        if b > a then swap a , b
                
        dim as double time1 , time2 , time3 , time4
        dim as ulongint b_and , a_and 
        
            time1 = timer
                'for x as longint = 1 to 1e6 
                    b_and = ( a and b)
                'next
            time2 = timer
            
            time3 = timer
                dim as string n1 = bin(a)
                dim as string n2 = bin(b)
                dim as string ans
                'for x as longint = 1 to 1e6 
                    dim as longint y = len(n1) - 1
                    dim as longint x = len(n2) - 1
                    do
                        n2[x] = ( n2[x] + n1[y] ) \ 2
                        x-= 1
                        y-= 1
                    loop until x = -1
                'next
                a_and = valulng("&B" + n2)
            time4 = timer
            
            'cls
            print
            print "n1 = " ; a
            print "n2 = " ; b
            print
            print "Builtin AND = " ; b_and , (time2 - time1)
            print "Albert  AND = " ; a_and , (time4 - time3)
            
            sleep
            
loop until inkey = chr(27)

sleep
end

albert
Posts: 6000
Joined: Sep 28, 2006 2:41
Location: California, USA

Re: Squares

Post by albert »

My latest AND function..

It works with any length of binary strings....

The line :
if b[x] < 98 then b[x] = 48 else b[x] = 49
can be converted to return certain bits , for any logic type. you can make an , and , or , xor , out of it..

Code: Select all


screen 19

'====================================================
'====================================================
function Albert_and( a as string , b as string ) as string
    dim as longint y = len(a) - 1
    for x as longint = len(b) - 1 to 0 step -1
        b[x]+= a[y]
        if b[x] < 98 then b[x] = 48 else b[x] = 49
        y-= 1
    next
    return b
end function
'====================================================
'====================================================

randomize

do
   
        dim as ulongint a = int( rnd*1e10 )
        dim as ulongint b = int( rnd*1e10 )
       
        if b > a then swap a , b
               
        dim as double time1 , time2 , time3 , time4
        
        dim as ulongint builtin_and
        dim as ulongint Redditt_and

'======================================
            'builtin AND
            time1 = timer
                for x as longint = 1 to 1e6
                    builtin_and = ( a and b)
                next
            time2 = timer
'======================================
           
'======================================
           'Albert_AND
                'set up for strings
                dim as string ans = ""
                dim as string n1 = bin(a)
                dim as string n2 = bin(b)
            time3 = timer
                for x as longint = 1 to 1e6
                    ans = Albert_and( n1 , n2 )
                next
                Redditt_and = val("&B" + ans)
            time4 = timer
'======================================
            
            dim as longint diff = builtin_and - Redditt_and 
            
            print
            print "n1 = " ; a
            print "n2 = " ; b
            print
            print "Builtin AND  = "   ; builtin_and   , "time = " ;  (time2 - time1)
            print "Redditt AND  = "  ; Redditt_and , "time = " ;  (time4 - time3)
            print "Diff = "; diff
            
            sleep
           
            if inkey = chr(27) then end
           
loop until inkey = chr(27)

end

Locked