8Bit Volladdierer

  • Hallöchen

    Ich hatte mal wieder Langeweile (Ja ich weiß, ich sollte fürs Abi lernen aber 3 Stunden lernen pro Tag muss reichen, auch bei Mathe, Physik LK), also hab ich mir gedacht, ich könnte mal wieder programmieren, was ich schon länger nicht gemacht hab, dementsprechend schlecht ist der Code wahrscheinlich auch :D

    Naja wie ich also hier im Forum krankhaft nach Ideen gesucht hab, ist mir ein Thread von minx begegnet, in dem von Bit Operationen die Rede war. Außerdem fiel der Begriff "Volladdierer" und naja, ich hab es mir in meiner Langeweile zur Aufgabe gemacht einfach mal einen zu skripten :D

    Fragen & Kritik gerne an mich, ich habe noch immer Langeweile :D

    Hier der Code:

    Spoiler anzeigen
    [autoit]

    #cs
    BOOLEAN & SHIT >=1 -> ODER 1 -> NICHT & -> UND
    Anmerkung: _DezZuDual gibt die Binärzahlen in umgekehrter Reihenfolge zurück, also ergäbe eine Eingabe von 13 nicht 1101 sondern 1011
    _Volladdieren8Bit rechnet nur mit den inversen Zahlen richtig
    _DualZuDez rechnet auch nur inverse Zahlen in die Richtigen Zahlen im 10er System um!
    #ce

    [/autoit] [autoit][/autoit] [autoit]

    $Zahl1 = InputBox("Eingabe 1", "Geben Sie die erste Zahl ein")
    $Zahl2 = InputBox("Eingabe 2", "Geben Sie die zweite Zahl ein")

    [/autoit] [autoit][/autoit] [autoit]

    $Dual1 = _DezZuDual($Zahl1)
    $Dual2 = _DezZuDual($Zahl2)

    [/autoit] [autoit][/autoit] [autoit]

    $Rueckgabewert = _Volladdieren8Bit($Dual1, $Dual2)
    MsgBox(0, "Ausgabe", "Das Ergebnis der Addition ist: " & _DualZuDez($Rueckgabewert))

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Rückgabewerte:
    ;$return[0-7] -> Dualzahlziffern
    ;$return[8] -> Übertrag (c)
    Func _Volladdieren8Bit($aZahlx, $aZahly)
    $aHA = _HalbAddierer($aZahlx[0], $aZahly[0])
    $aVA1 = _VollAddierer($aZahlx[1], $aZahly[1], $aHA[1])
    $aVA2 = _VollAddierer($aZahlx[2], $aZahly[2], $aVA1[1])
    $aVA3 = _VollAddierer($aZahlx[3], $aZahly[3], $aVA2[1])
    $aVA4 = _VollAddierer($aZahlx[4], $aZahly[4], $aVA3[1])
    $aVA5 = _VollAddierer($aZahlx[5], $aZahly[5], $aVA4[1])
    $aVA6 = _VollAddierer($aZahlx[6], $aZahly[6], $aVA5[1])
    $aVA7 = _VollAddierer($aZahlx[7], $aZahly[7], $aVA6[1])

    [/autoit] [autoit][/autoit] [autoit]

    Dim $return[9]
    $return[0] = $aHA[0]
    $return[1] = $aVA1[0]
    $return[2] = $aVA2[0]
    $return[3] = $aVA3[0]
    $return[4] = $aVA4[0]
    $return[5] = $aVA5[0]
    $return[6] = $aVA6[0]
    $return[7] = $aVA7[0]
    $return[8] = $aVA7[1]

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Return $return
    EndFunc ;==>_Volladdieren8Bit

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Rückgabewerte:
    ;$return[0] -> Summe (s)
    ;$return[1] -> Übertrag (c)
    Func _VollAddierer($fX, $fY, $fCin)
    $aHA1 = _HalbAddierer($fX, $fY)
    $aHA2 = _HalbAddierer($fCin, $aHA1[0])

    [/autoit] [autoit][/autoit] [autoit]

    $fOr = $aHA1[1] Or $aHA2[1]

    [/autoit] [autoit][/autoit] [autoit]

    Dim $return[2]
    $return[0] = $aHA2[0]
    $return[1] = $fOr
    Return $return
    EndFunc ;==>_VollAddierer

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Rückgabewerte:
    ;$return[0] -> Summe (s)
    ;$return[1] -> Übertrag (c)
    Func _HalbAddierer($fX, $fY)
    $fOr = $fX Or $fY
    $fAnd1 = $fX And $fY

    [/autoit] [autoit][/autoit] [autoit]

    $fNot = Not $fAnd1

    [/autoit] [autoit][/autoit] [autoit]

    $fAnd2 = $fOr And $fNot
    Dim $return[2]
    $return[0] = $fAnd2
    $return[1] = $fAnd1
    Return $return
    EndFunc ;==>_HalbAddierer

    [/autoit] [autoit][/autoit] [autoit]

    #cs
    ##########
    Die Dezimalzahl 28 wird ins 2er-System umgewandelt

    [/autoit] [autoit][/autoit] [autoit]

    Gehe nach folgendem Verfahren vor:
    (1) Teile die Zahl mit Rest durch 2.
    (2) Der Divisionsrest ist die nächste Ziffer (von rechts nach links).
    (3) Falls der (ganzzahlige) Quotient = 0 ist, bist du fertig,
    andernfalls nimm den (ganzzahligen) Quotienten als neue Zahl
    und wiederhole ab (1).

    [/autoit] [autoit][/autoit] [autoit]

    28 : 2 = 14 Rest: 0
    14 : 2 = 7 Rest: 0
    7 : 2 = 3 Rest: 1
    3 : 2 = 1 Rest: 1
    1 : 2 = 0 Rest: 1

    [/autoit] [autoit][/autoit] [autoit]

    Resultat: 11100
    ##########
    #ce
    Func _DezZuDual($iZahl)
    Dim $aKurzerArray[1]
    Dim $aAusgabe[8]
    Local $i = 0

    [/autoit] [autoit][/autoit] [autoit]

    Do
    ReDim $aKurzerArray[$i + 1]
    $iZwischenergebnis = Int($iZahl / 2)
    $aKurzerArray[$i] = $iZahl - 2 * $iZwischenergebnis
    $iZahl = $iZwischenergebnis
    $i = $i + 1
    Until $iZwischenergebnis = 0

    [/autoit] [autoit][/autoit] [autoit]

    $iLaenge = UBound($aKurzerArray)
    For $i = $iLaenge To 7 Step 1
    ReDim $aKurzerArray[$i + 1]
    $aKurzerArray[$i] = 0
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $aKurzerArray
    EndFunc ;==>_DezZuDual

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #cs
    ##########
    Die Zahl 11100 (2er-System) wird ins Dezimalsystem umgewandelt

    [/autoit] [autoit][/autoit] [autoit]

    Jede Stelle der Zahl hat den Wert der entsprechenden 2er-Potenz.
    Die der ersten Ziffer von rechts entsprechende Potenz ist 2º = 1.
    Nimm jede Ziffer mal mit der entsprechenden Potenz und summiere.
    Gehe am besten von rechts nach links vor:

    [/autoit] [autoit][/autoit] [autoit]

    0 · 1 = 0
    0 · 2 = 0
    1 · 4 = 4
    1 · 8 = 8
    1 · 16 = 16
    ———
    28
    ##########
    #ce
    Func _DualZuDez($aZahl)
    Local $iAusgabe
    Dim $aZwischenergebnis[9]

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To 8 Step 1
    $aZwischenergebnis[$i] = $aZahl[$i] * 2 ^ ($i)
    $iAusgabe = $iAusgabe + $aZwischenergebnis[$i]
    Next
    Return $iAusgabe
    EndFunc ;==>_DualZuDez

    [/autoit]

    Viel Spaß damit

    DFPWare

  • Müsste das von der Theorie her nicht auch mit den hauseigenen Bit Funktionen gehen ?

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal

  • ich habs mal so kurz wie möglich nur mit den bit Funktionen gemacht

    Spoiler anzeigen
    [autoit]

    Dim $i8bitB[8] = [0, 0, 0, 0, 0, 0, 0, 0], $i8bitA[8] = [0, 0, 0, 0, 0, 0, 0, 0]
    Global $iergebnis[8]; 0=1bit 1=2bit 2=3bit 3=4bit
    $iergebnis[0] = BitXOR(BitXOR($i8bitA[0], $i8bitB[0]), 0)
    $iergebnis[1] = BitXOR(BitXOR($i8bitA[1], $i8bitB[1]), BitOR(BitAND($i8bitA[0], $i8bitB[0]), BitAND(0, BitXOR($i8bitA[0], $i8bitB[0]))))
    $iergebnis[2] = BitXOR(BitXOR($i8bitA[2], $i8bitB[2]), BitOR(BitAND($i8bitA[1], $i8bitB[1]), BitAND(BitOR(BitAND($i8bitA[0], $i8bitB[0]), BitAND(0, BitXOR($i8bitA[0], $i8bitB[0]))), BitXOR($i8bitA[1], $i8bitB[1]))))
    $iergebnis[3] = BitXOR(BitXOR($i8bitA[3], $i8bitB[3]), BitOR(BitAND($i8bitA[2], $i8bitB[2]), BitAND(BitOR(BitAND($i8bitA[1], $i8bitB[1]), BitAND(BitOR(BitAND($i8bitA[0], $i8bitB[0]), BitAND(0, BitXOR($i8bitA[0], $i8bitB[0]))), BitXOR($i8bitA[1], $i8bitB[1]))), BitXOR($i8bitA[2], $i8bitB[2]))))
    $iergebnis[4] = BitXOR(BitXOR($i8bitA[4], $i8bitB[4]), BitOR(BitAND($i8bitA[3], $i8bitB[3]), BitAND(BitOR(BitAND($i8bitA[2], $i8bitB[2]), BitAND(BitOR(BitAND($i8bitA[1], $i8bitB[1]), BitAND(BitOR(BitAND($i8bitA[0], $i8bitB[0]), BitAND(0, BitXOR($i8bitA[0], $i8bitB[0]))), BitXOR($i8bitA[1], $i8bitB[1]))), BitXOR($i8bitA[2], $i8bitB[2]))), BitXOR($i8bitA[3], $i8bitB[3]))))
    $iergebnis[5] = BitXOR(BitXOR($i8bitA[5], $i8bitB[5]), BitOR(BitAND($i8bitA[4], $i8bitB[4]), BitAND(BitOR(BitAND($i8bitA[3], $i8bitB[3]), BitAND(BitOR(BitAND($i8bitA[2], $i8bitB[2]), BitAND(BitOR(BitAND($i8bitA[1], $i8bitB[1]), BitAND(BitOR(BitAND($i8bitA[0], $i8bitB[0]), BitAND(0, BitXOR($i8bitA[0], $i8bitB[0]))), BitXOR($i8bitA[1], $i8bitB[1]))), BitXOR($i8bitA[2], $i8bitB[2]))), BitXOR($i8bitA[3], $i8bitB[3]))), BitXOR($i8bitA[4], $i8bitB[4]))))
    $iergebnis[6] = BitXOR(BitXOR($i8bitA[6], $i8bitB[6]), BitOR(BitAND($i8bitA[5], $i8bitB[5]), BitAND(BitOR(BitAND($i8bitA[4], $i8bitB[4]), BitAND(BitOR(BitAND($i8bitA[3], $i8bitB[3]), BitAND(BitOR(BitAND($i8bitA[2], $i8bitB[2]), BitAND(BitOR(BitAND($i8bitA[1], $i8bitB[1]), BitAND(BitOR(BitAND($i8bitA[0], $i8bitB[0]), BitAND(0, BitXOR($i8bitA[0], $i8bitB[0]))), BitXOR($i8bitA[1], $i8bitB[1]))), BitXOR($i8bitA[2], $i8bitB[2]))), BitXOR($i8bitA[3], $i8bitB[3]))), BitXOR($i8bitA[4], $i8bitB[4]))), BitXOR($i8bitA[5], $i8bitB[5]))))
    $iergebnis[7] = BitXOR(BitXOR($i8bitA[7], $i8bitB[7]), BitOR(BitAND($i8bitA[6], $i8bitB[6]), BitAND(BitOR(BitAND($i8bitA[5], $i8bitB[5]), BitAND(BitOR(BitAND($i8bitA[4], $i8bitB[4]), BitAND(BitOR(BitAND($i8bitA[3], $i8bitB[3]), BitAND(BitOR(BitAND($i8bitA[2], $i8bitB[2]), BitAND(BitOR(BitAND($i8bitA[1], $i8bitB[1]), BitAND(BitOR(BitAND($i8bitA[0], $i8bitB[0]), BitAND(0, BitXOR($i8bitA[0], $i8bitB[0]))), BitXOR($i8bitA[1], $i8bitB[1]))), BitXOR($i8bitA[2], $i8bitB[2]))), BitXOR($i8bitA[3], $i8bitB[3]))), BitXOR($i8bitA[4], $i8bitB[4]))), BitXOR($i8bitA[5], $i8bitB[5]))), BitXOR($i8bitA[6], $i8bitB[6]))))
    MsgBox(0, "", $iergebnis[7] & $iergebnis[6] & $iergebnis[5] & $iergebnis[4] & $iergebnis[3] & $iergebnis[2] & $iergebnis[1] & $iergebnis[0])

    [/autoit]

    €: Namen angepasst
    €2: Noch kürzer und (vieleicht) verständlicher (480 Zeichen)

    Spoiler anzeigen
    [autoit]


    Dim $i8bitB[8] = [1, 0, 0, 0, 0, 0, 0, 0], $i8bitA[8] = [1, 1, 0, 0, 0, 0, 0, 0], $iergebnis[8]; 0=1bit 1=2bit 2=3bit 3=4bit
    Global $iuebertrag=0
    For $1=0 To 7
    $iergebnis[$1] = BitXOR(BitXOR($i8bitA[$1], $i8bitB[$1]), $iuebertrag)
    $iuebertrag=BitOR(BitAND($i8bitA[$1], $i8bitB[$1]), BitAND(BitXOR($i8bitA[$1], $i8bitB[$1]) ,$iuebertrag))
    Next
    MsgBox(0, "", $iergebnis[7] & $iergebnis[6] & $iergebnis[5] & $iergebnis[4] & $iergebnis[3] & $iergebnis[2] & $iergebnis[1] & $iergebnis[0])

    [/autoit]

    4 Mal editiert, zuletzt von bollen (9. April 2013 um 19:29)

  • Hallöchen nochmal

    minx:
    Das war schon beabsichtigt, dass es nicht allzu kurz geworden ist ;) Vielen Dank :)

    bollen:
    Naja wenige Zeilen sind das zwar allerdings ist der Funktionsumfang nicht unbedingt berauschend :D
    Hier mal meine möglichst kurze Version ohne die Bit Befehle:

    Spoiler anzeigen
    [autoit]

    Dim $Dual1[8] = [1, 1, 1, 1, 0, 1, 1, 0], $Dual2[8] = [0, 0, 0, 0, 1, 0, 0, 1]
    $Ergebnis = _Volladdieren8Bit($Dual1,$Dual2)
    MsgBox(0,"Ausgabe","Ergebnis: " & $Ergebnis[7] & $Ergebnis[6] & $Ergebnis[5] & $Ergebnis[4] & $Ergebnis[3] & $Ergebnis[2] & $Ergebnis[1] & $Ergebnis[0])
    Func _Volladdieren8Bit($aZahlx, $aZahly)
    $aHA = _HalbAddierer($aZahlx[0], $aZahly[0])
    $aVA1 = _VollAddierer($aZahlx[1], $aZahly[1], $aHA[1])
    $aVA2 = _VollAddierer($aZahlx[2], $aZahly[2], $aVA1[1])
    $aVA3 = _VollAddierer($aZahlx[3], $aZahly[3], $aVA2[1])
    $aVA4 = _VollAddierer($aZahlx[4], $aZahly[4], $aVA3[1])
    $aVA5 = _VollAddierer($aZahlx[5], $aZahly[5], $aVA4[1])
    $aVA6 = _VollAddierer($aZahlx[6], $aZahly[6], $aVA5[1])
    $aVA7 = _VollAddierer($aZahlx[7], $aZahly[7], $aVA6[1])
    Dim $return[9]
    $return[0] = $aHA[0]
    $return[1] = $aVA1[0]
    $return[2] = $aVA2[0]
    $return[3] = $aVA3[0]
    $return[4] = $aVA4[0]
    $return[5] = $aVA5[0]
    $return[6] = $aVA6[0]
    $return[7] = $aVA7[0]
    $return[8] = $aVA7[1]
    Return $return
    EndFunc ;==>_Volladdieren8Bit
    Func _VollAddierer($fX, $fY, $fCin)
    $aHA1 = _HalbAddierer($fX, $fY)
    $aHA2 = _HalbAddierer($fCin, $aHA1[0])
    $fOr = $aHA1[1] Or $aHA2[1]
    Dim $return[2]
    $return[0] = $aHA2[0]
    $return[1] = $fOr
    Return $return
    EndFunc ;==>_VollAddierer
    Func _HalbAddierer($fX, $fY)
    $fOr = $fX Or $fY
    $fAnd1 = $fX And $fY

    [/autoit] [autoit][/autoit] [autoit]

    $fNot = Not $fAnd1

    [/autoit] [autoit][/autoit] [autoit]

    $fAnd2 = $fOr And $fNot
    Dim $return[2]
    $return[0] = $fAnd2
    $return[1] = $fAnd1
    Return $return
    EndFunc ;==>_HalbAddierer

    [/autoit]

    Hat zwar viermal so viele Zeilen, ist allerdings übersichtlicher und hat nur 1385 Zeichen (Deine Version dagegen hat 2937) :D

    DFPWare