メモ@inudaisho

君見ずや出版 / 興味次第の調べ物置き場

減算器を実装してみた

Subtractor - Wikipedia

 Wikipediaの英語版の方に減算器の項目があり、論理回路がのってたので、それをPython3で実装してみた。ついでに半加算器と半減算器もつけた。

def cSub(x,y,b):
    return ((x ^ y) ^ b, (~x & y)| (~(x ^ y) & b))

def fSub( iA,iB):
    bA = format(iA,'b')
    bB = format(iB,'b')
    iLA = len(bA)
    iLB = len(bB)
    if iLA > iLB:
        bB = "0"*(iLA-iLB) + bB
    else:
        bA = "0"*(iLB-iLA) + bA
        iLA = iLB

    iB = 0
    sBin = ""
    sD = ""
    sBout = ""
    for i in range(iLA):
        sBin += str(iB)
        iD , iB = cSub(int(bA[i]),int(bB[i]),iB)
        sBout += str(iB)
        sD += str(iD)

    iD = int(sD,2)
    iBin = int(sBin,2)
    iBout = int(sBout,2)
    return iD,iBin,iBout,iD + iBin - (iBout << 1)

for a,b in [(3445,5189),(454,45)]:

    print("______",a,b,"______")
    #半加算器 AND NOT OR
    print( a+b , "半加",((a & b ) << 1) + (( a | b) & ~(a & b)) )
    #半加算器 XOR AND
    print( a+b , "半加",((a & b ) << 1) + (a ^ b))
    print( a-b,"半減",(a ^ b),(~a & b), (a ^ b) - ( (~a & b) << 1) )
    print( a-b,"全減",fSub(a,b))

 この結果

______ 3445 5189 ______
8634 半加 8634
8634 半加 8634
-1744 半減 6448 4096 -1744
-1744 全減 (4400, 2048, 4096, -1744)

______ 454 45 ______
499 半加 499
499 半加 499
409 半減 491 41 409
409 全減 (501, 30, 61, 409)

 減算器、D(Difference) に差分が出てくるんだとおもっていたら全然違っていた。3445 - 5189 を計算さすと D に4400が出てくる。Bin(上の桁のBorrow) Bout(計算で出たBorrow) をそれぞれ記録して出してみると、2048、4096で、これをD + Bin - 2 * Bout としてようやく - 1744 がでてくる。加算器がそのままでてくるのに比べると大きな違いだ。borrow というのは桁下がりで、下の方で解決するんだとおもってたんだが、こうして余らせたのを最後にやりくりしてどうにかするらしい。調べたときに出てきた「補数をつかって減算を加算で実現」というのとちょっと違う。

 これですこしはわかるかとAtCoder ABC050 D XorSum を眺めたがやっぱりよくわからんので痛手を負う前にこれでも書いて心を慰めながら寝ることにした。つぎは米子高専のこれ↓でも勉強するかな...(ググったら出てきた)

ディジタル回路 (3年必修 2単位)

(これを読んで修正したのが翌日の記事)

論理回路入門(第3版)

論理回路入門(第3版)

OHM大学テキスト 論理回路

OHM大学テキスト 論理回路