Jump to content

Adder Circuit


LimeSeed
 Share

Recommended Posts

Here's an adder circuit that i have been working on. you type in two decimal numbers and it then converts them to binary where it does exclusive or functions (XOR) and and functions (to figure out the carries) to solve problems a very basic way =P it is just to give me an idea of how the actual circuit works, not that this script is in any way efficient since i used my own functions :) enjoy!

;Adder circut currently works!

#include <String.au3>
#include <guiconstants.au3>

Global $binanswer
Global $decimal

GUICreate("Adder Circuit", 200, 250)
$n1 = guictrlcreateinput("Input First Number Here", 5, 20, 190, 20)
$l1 = guictrlcreatelabel("First Number's Binary Value", 5, 45, 190, 20)
$n2 = guictrlcreateinput("Input Second Number Here", 5, 70, 190, 20)
$l2 = guictrlcreatelabel("Second Number's Binary Value", 5, 95, 190, 20)
$a1 = guictrlcreatelabel("Answer's Binary Value", 5, 145, 190, 20)
$a2 = guictrlcreatelabel("Answer's Decimal Value", 5, 170, 190, 20)
$calc = guictrlcreatebutton("Calculate", 5, 195, 190, 50)
guisetstate()

While 1
    sleep(20)
    $msg = guigetmsg()
    if $msg = -3 then Exit
    if $msg = $calc Then
        $decimal = ""
        $binanswer = ""
        $carry = 0 
        $1 = guictrlread($n1)
        $2 = guictrlread($n2)
        $number1 = _Binary($1)
        $number2 = _Binary($2)
        
        ;make both numbers have equal place values
        Do
            $length1 = stringlen($number1)
            $length2 = stringLen($number2)
            if ($length1 > $length2) Then
                $number2 = "0" & $number2
            elseif ($length1 < $length2) Then
                $number1 = "0" & $number1
            EndIf
        Until ($length1 = $length2)

        ;set data so user can see numbers
        guictrlsetdata($l1, $number1)
        guictrlsetdata($l2, $number2)
        
        ;take length again to see how big to make binary addition array
        $length1 = stringlen($number1)
        
        $add1 = stringsplit($number1, "")
        $add2 = stringsplit($number2, "")
        ;Local $binanswer = ""
        for $i = $length1 to 1  step -1
            $binanswer = $binanswer & _Xor($add1[$i], $add2[$i])
        Next
        $binanswer = _StringReverse($binanswer)
        if $carry = 1 Then
            $binanswer = "1" & $binanswer
            $carry = 0
        EndIf
        guictrlsetdata($a1, $binanswer)
        ;converting from binary to decimal
        $c = _StringReverse($binanswer)
        $d = StringSplit($c, "")
        for $i = 1 to $d[0] step 1
            if $d[$i] = 1 Then $decimal += 2^($i-1)
        Next
        guictrlsetdata($a2, $decimal)
    EndIf
WEnd

;special thanks to descendant for making this function :P
Func _Binary($iNumber)
    Local $Bin=""
    While $iNumber
        If BitAND($iNumber,1) Then 
            $Bin='1'&$Bin
        Else
            $Bin='0'&$Bin
        EndIf
        $iNumber=BitShift($iNumber,1)
    WEnd
    Return $bin
EndFunc

Func _Xor($1, $2)
    Local $bit
    if ((($1 = "1") and ($2 = "0")) or (($1 = "0") and ($2 = "1"))) Then
        if $carry = 1 Then
            $bit = 0
            $carry = 1
        Else
            $bit = 1
            $carry = 0
        EndIf
    Elseif (($1 = "1") and ($2 = "1")) Then
        if $carry = 1 Then
            $bit = 1
            $carry = 1
        else
            $bit = 0
            $carry = 1
        EndIf
    Elseif (($1 = "0") and ($2 = "0")) Then
        if $carry = 1 Then
            $bit = 1
            $carry = 0
        Else
            $bit = 0
            $carry = 0
        EndIf
    EndIf
    Return $bit
EndFunc
Edited by LimeSeed
global $warming = true
Link to comment
Share on other sites

Very nice work. I write another version based on your GUI, hope you like:

#include <String.au3>

Global $CARRY = 0
Global $B_OUT = ""

$GUI = GUICreate("Adder Circuit", 200, 250)
$Number1 = GUICtrlCreateInput("Input First Number Here", 5, 20, 190, 20)
$Label1 = GuiCtrlCreateLabel("First Number's Binary Value", 5, 45, 190, 20)
$Number2 = GuiCtrlCreateInput("Input Second Number Here", 5, 70, 190, 20)
$Label2 = GuiCtrlCreateLabel("Second Number's Binary Value", 5, 95, 190, 20)
$Value = GuiCtrlCreateLabel("Answer's Binary Value", 5, 145, 190, 20)
$Label3 = GuiCtrlCreateLabel("Answer's Decimal Value", 5, 170, 190, 20)
$Calculate = GuiCtrlCreateButton("Calculate", 5, 195, 190, 50)
GUISetState(@SW_SHOW,$GUI)

While 1
    $MSG = GUIGetMsg()
    If $MSG = $Calculate Then
        $Result = Call("Calc",GUICtrlRead($Number1),GUICtrlRead($Number2))
        GUICtrlSetData($Label1,_Binary(GUICtrlRead($Number1)))
        GUICtrlSetData($Label2,_Binary(GUICtrlRead($Number2)))
        GUICtrlSetData($Value,_Decimal($Result))
        GUICtrlSetData($Label3,$Result)
    ElseIf $MSG = -3 Then
        Exit
    EndIf
    Sleep(20)
WEnd

Func Calc($Number1,$Number2)
    $CARRY = 0
    $B_OUT = ""
    $Number1 = _Binary($Number1)
    $Number2 = _Binary($Number2)
    If StringLen($Number1) > StringLen($Number2) Then
        $Number2 = _StringRepeat("0",StringLen($Number1)-StringLen($Number2)) & $Number2
    ElseIf StringLen($Number1) < StringLen($Number2) Then
        $Number1 = _StringRepeat("0",StringLen($Number2)-StringLen($Number1)) & $Number1
    EndIf
    For $INDEX = StringLen($Number1) To 1 Step -1
        $A = StringMid($Number1,$INDEX,1)
        $B = StringMid($Number2,$INDEX,1)
        Cell(Number($A),Number($B),$CARRY)
    Next
    $OUT = $CARRY & _StringReverse($B_OUT)
    If StringLeft($OUT,1) = "0" Then $OUT = StringTrimLeft($OUT,1)
    Return $OUT
EndFunc

Func Cell($A,$B,$C)
    $STEP1 = BitXOR($A,$B)
    $STEP2 = BitXOR($STEP1,$C)
    $B_OUT &= String($STEP2)
    $STEP3 = BitAND($STEP1,$C)
    $STEP4 = BitAND($A,$B)
    $CARRY = BitOR($STEP3,$STEP4)
EndFunc

Func _Decimal($Number)
    Local $DEC = 0
    For $INDEX = 1 To StringLen($Number)
        $DEC += Number(StringMid($Number,$INDEX,1))*2^(StringLen($Number)-$INDEX)
    Next
    Return $DEC
EndFunc

Func _Binary($iNumber)
    Local $Bin=""
    While $iNumber
        If BitAND($iNumber,1) Then
            $Bin='1'&$Bin
        Else
            $Bin='0'&$Bin
        EndIf
        $iNumber=BitShift($iNumber,1)
    WEnd
    Return $bin
EndFunc

When the words fail... music speaks.

Link to comment
Share on other sites

Nice project. I thought I could do better so here it is:

; This is an implementation of the ripple carry adder
; http://en.wikipedia.org/wiki/Adder_(electronics)#Ripple_carry_adder

#include <Math.au3>
#include <String.au3>

; using strings for simple user input
Dim $numA =   "0100" ; 4
Dim $numB = "1100" ; 12
; Expecting a result of 16: This is 10000

; Try a big value, such as 11111111
; And add a value 1 to it, so overflow will occur
; $numA = "11111111"
; $numB = "00000001"

; Gets the longest string of the two and turns them into a binary array like: [1,0,1,1]
Dim $len = _LongestString($numA,$numB)
; Alternatively you can set this to a number like 8 to indicate the number of full adders to use
$len = 8 ; 8 bits full adder

Dim $binA = _BinStringToBinArray($numA, $len)
Dim $binB = _BinStringToBinArray($numB, $len)

; Makes a variable for the result number
Dim $sum[$len]
Dim $carry = 0

For $i = 0 to $len-1
    
    $res = _FullAdder( $binA[$i], $binB[$i], $carry )
    
    $sum[$i] = $res[0]
    $carry = $res[1]
    
Next

If ( $carry == 1 ) Then ; Overflow 
    MsgBox(0,"AutoIt Implementation of Full Adder","Overflow has occured, your results will not be accurate.")
EndIf

MsgBox(0, "AutoIt Implementation of Full Adder", "Result: " & _BinArrayToBinString($sum) )

;; Utility function for IO

; Turns a string "1011" into a 'binary array' : [1,0,1,1]
Func _BinStringToBinArray($in, $len = 8)
    $in = _StringReverse($in) ; it would've been easier to switch the MSB and LSB but whatever
    
    Local $t = StringSplit($in,"")
    Local $ret[$len]
    
    For $i = 0 to $len-1
        $ret[$i] = 0
    Next
    
    For $i = 1 to UBound($t)-1
        $ret[$i-1] = Number($t[$i])
    Next
    
    Return $ret
EndFunc

; Turns a string "1011" into a 'binary array' : [1,0,1,1]
Func _BinArrayToBinString($in)
    Local $ret = ""
    For $i = UBound($in)-1 to 0 Step -1
        $ret &= String($in[$i])
    Next
    Return $ret
EndFunc

; Returns the length of the longest string
Func _LongestString($a,$b) 
    Return _Max(StringLen($a),StringLen($b) )
EndFunc

;; Binary mathematical functions

; http://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder
Func _FullAdder($a, $b, $cIn = 0)
    Local $cOut = BitOR( BitAND($a,$b)  , BitAND($cIn, BitXOR($a,$b) ))
    Local $S = BitXOR(BitXOR($a,$b) ,$cIn)
    local $ret[2] = [$S,$cOut]
    Return $ret
EndFunc

; http://en.wikipedia.org/wiki/Adder_(electronics)#Half_adder
Func _HalfAdder($a,$b) 
    Local $S = BitXOR($a,$b)  ; sum
    Local $C = BitAND($a,$b)  ; carry
    local $ret[2] = [$S,$C]
    Return $ret
EndFunc

Someone else can make a GUI and worry about the decimal - binary conversion for ease of use.

Edited by Manadar
Link to comment
Share on other sites

Nice work Manadar. Next step: difference operation

It should be easy:

1001 ;Number 9

0011 ;Number -4

--------- Add operation

1100 - Delete MSB

-------------------------

100 - Add 1

001

----

101 ; The result, number 5

If you know how 8 bits two's complement adding works then you don't even have to change the code.

0000 0100 is the number 4 . The number -4 is 1111 1100.

Put this into the code:

Dim $numA = "00001001" ; 9

Dim $numB = "11111100" ; -4

It will say an overflow has occured but you may ignore this according to two's complement addition.

The result is: 0000 0101 which is 5.

Edited by Manadar
Link to comment
Share on other sites

... since i used my own functions

Func _Binary($iNumber)
    Local $Bin=""
    While $iNumber
        If BitAND($iNumber,1) Then 
            $Bin='1'&$Bin
        Else
            $Bin='0'&$Bin
        EndIf
        $iNumber=BitShift($iNumber,1)
    WEnd
    Return $bin
EndFunc
Be careful about taking ownership for someone else's work. It pays to acknowledge people's efforts.

Might as well borrow the new Binary conversion function I just posted and put your name on it, since negative #'s crash your script.

Ascend4nt

Link to comment
Share on other sites

Be careful about taking ownership for someone else's work. It pays to acknowledge people's efforts.

Might as well borrow the new Binary conversion function I just posted and put your name on it, since negative #'s crash your script.

Ascend4nt

yea sorry, i though my function was in there :) good work, but this is entirely my own, sorry ascendant

;Adder circut currently works!

#include <String.au3>
#include <guiconstants.au3>

Global $binanswer
Global $decimal

GUICreate("Adder Circuit", 200, 250)
$n1 = guictrlcreateinput("Input First Number Here", 5, 20, 190, 20)
$l1 = guictrlcreatelabel("First Number's Binary Value", 5, 45, 190, 20)
$n2 = guictrlcreateinput("Input Second Number Here", 5, 70, 190, 20)
$l2 = guictrlcreatelabel("Second Number's Binary Value", 5, 95, 190, 20)
$a1 = guictrlcreatelabel("Answer's Binary Value", 5, 145, 190, 20)
$a2 = guictrlcreatelabel("Answer's Decimal Value", 5, 170, 190, 20)
$calc = guictrlcreatebutton("Calculate", 5, 195, 190, 50)
guisetstate()

While 1
    sleep(20)
    $msg = guigetmsg()
    if $msg = -3 then Exit
    if $msg = $calc Then
        $decimal = ""
        $binanswer = ""
        $carry = 0 
        $1 = guictrlread($n1)
        $2 = guictrlread($n2)
        $number1 = _Binary($1)
        $number2 = _Binary($2)
        
        ;make both numbers have equal place values
        Do
            $length1 = stringlen($number1)
            $length2 = stringLen($number2)
            if ($length1 > $length2) Then
                $number2 = "0" & $number2
            elseif ($length1 < $length2) Then
                $number1 = "0" & $number1
            EndIf
        Until ($length1 = $length2)

        ;set data so user can see numbers
        guictrlsetdata($l1, $number1)
        guictrlsetdata($l2, $number2)
        
        ;take length again to see how big to make binary addition array
        $length1 = stringlen($number1)
        
        $add1 = stringsplit($number1, "")
        $add2 = stringsplit($number2, "")
        ;Local $binanswer = ""
        for $i = $length1 to 1  step -1
            $binanswer = $binanswer & _Xor($add1[$i], $add2[$i])
        Next
        $binanswer = _StringReverse($binanswer)
        if $carry = 1 Then
            $binanswer = "1" & $binanswer
            $carry = 0
        EndIf
        guictrlsetdata($a1, $binanswer)
        ;converting from binary to decimal
        $c = _StringReverse($binanswer)
        $d = StringSplit($c, "")
        for $i = 1 to $d[0] step 1
            if $d[$i] = 1 Then $decimal += 2^($i-1)
        Next
        guictrlsetdata($a2, $decimal)
    EndIf
WEnd

Func _binary($num) ;converts a number to binary!
    dim $string = ""
    Do
        $num = $num/2
        if(floor($num) = $num) then
            $string = $string & "0"
        Else
            $string = $string & "1"
            $num -= .5
        EndIf
    Until ($num = 0)
    $string = _stringreverse($string)
   Return $string
EndFunc

Func _Xor($1, $2)
    Local $bit
    if ((($1 = "1") and ($2 = "0")) or (($1 = "0") and ($2 = "1"))) Then
        if $carry = 1 Then
            $bit = 0
            $carry = 1
        Else
            $bit = 1
            $carry = 0
        EndIf
    Elseif (($1 = "1") and ($2 = "1")) Then
        if $carry = 1 Then
            $bit = 1
            $carry = 1
        else
            $bit = 0
            $carry = 1
        EndIf
    Elseif (($1 = "0") and ($2 = "0")) Then
        if $carry = 1 Then
            $bit = 1
            $carry = 0
        Else
            $bit = 0
            $carry = 0
        EndIf
    EndIf
    Return $bit
EndFunc
global $warming = true
Link to comment
Share on other sites

You don't have to *not* use my code, but I would appreciate acknowledgments, as I try to do in all my projects. It also helps lead people from one interesting thing to another if you find you like someone's code

A

Link to comment
Share on other sites

You don't have to *not* use my code, but I would appreciate acknowledgments, as I try to do in all my projects. It also helps lead people from one interesting thing to another if you find you like someone's code

A

i know, i just wanted to use my own cuz it makes me feel more special :) and i gave you credit in the script now :)

Edited by LimeSeed
global $warming = true
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...