1. 程式人生 > >Python用字串做二進位制乘法和Python呼叫內建進位制轉換我踩的坑

Python用字串做二進位制乘法和Python呼叫內建進位制轉換我踩的坑

注意本文加法的思想來源於 https://blog.csdn.net/qiubingcsdn/article/details/82263114
其餘為我自己做的

  • 字串str的末位是實際上計算的首位,所以第一步是翻轉字串

首先弄清楚python的字串列表有2種取值順序:
從左到右索引預設0開始的

s = 'ilovepython'

s[0]的結果是i

然後從右到左索引預設-1開始的

s = 'ilovepython'

s[-1]的結果是n

str=‘1000’
應該從末尾的0開始計算,為了方便首先翻轉。Python可以巧妙用元組的特性。

a =
a[::-1]
  • 乘法可以看作每層相與之後的加法,呼叫加法的時候注意理清楚邏輯

    首先倒序的目的只是為了邏輯上的最低位為str[0],只存在於函式的計算過程中,這樣算出來的結果也是與我們直接看到的相反。因此判斷是否要把這個字串倒序只需要分為:
    需要這個字串來直接進行加減計算的/字串直接相加而成的→倒序
    這個字串作為函式的引數/呼叫函式的結果→正序

  • 注意變數的位置到底在哪層迴圈裡面,區域性變數容易被誤清零

    還有一個問題,for中的range也是一個數列,數字數列。
    因此for i in range(1,5)相當於 for i in [1, 2, 3, 4]
    for i in range(5)也相當於 for i in [1, 2, 3, 4]


    一些細節上的小問題。建議遇到問題先谷歌翻譯試圖自行理解,比直接搜CSDN要快得多。

  • int()不能使用顯式base轉換非字串
    int() can’t convert non-string with explicit base

  • b_sum = int(b[index])
    ValueError: invalid literal for int() with base 10: 'b'
    

    int()的基數為10的文字無效:
    invalid literal for int() with base 10:
    意思是這裡的b[index]中的index出現了十進位制無法識別的東西

    int("12345",2)
    

    報的也是這個錯誤,因為這裡的意思是,把【二進位制數】12345強行轉換成十進位制,但是2345顯然不是二進位制數,所以這裡是錯誤的。

  • 輸入的型別不能被強制轉換為整型,比如輸入了一個浮點型
    oct() takes exactly one argument

  • str物件不能直接強制愛轉換成整數
    ‘str’ object cannot be interpreted as an integer

  • 字串不可直接下標更改值,只有列表可以。
    TypeError: ‘str’ object doesn’t support item deletio


我遇到的錯誤前情 :
八進位制和十六進位制只輸入11110000之類的0和1是沒問題的。但是出現了別的數字就不行。

出現問題的原因:
oct(x)
hex(x)
裡面的引數x是十進位制數字
但是函式的返回值是帶有 “0o” "0x"的字串
使用前需要先轉換成十進位制數字!

int(a, 8) 是說明a是一個八進位制數,需要被轉換成十進位制!這個時候,為了區分十進位制和八進位制,a必須要有字首"0o"
千萬不要偷懶覺得八進位制不會像十六進位制一樣出現無法識別的ABC就直接輸入了。
比如:

>>a = input("請輸入第一個八進位制數: ")
10
>>p = beBin(int(a))

因為輸入八進位制的10,實際上a=9,但是直接輸入的時候,a=10
後面計算全部出錯!

原始碼

def addBinary(a, b):
    if len(a) < len(b):  # 以長的二進位制字串為遍歷起點
        temp = a
        a = b
        b = temp
    a = a[::-1]  # 倒序二進位制字串
    b = b[::-1]
    extra = 0  # 進位
    new_binary = ""
    for index, num in enumerate(a):  # 遍歷
        if index > len(b) - 1:  # 判斷短的二進位制字串是否越界
            b_sum = 0
        else:
            b_sum = int(b[index])
        new_binary = new_binary + str((int(num) + b_sum + extra) % 2)  # 二進位制加法運算
        if int(num) + b_sum + extra > 1:  # 是否進位
            extra = 1
        else:
            extra = 0
    if extra == 1:  # 最高位是否進位
        new_binary = new_binary + "1"
    return new_binary[::-1]  # 倒序輸出


def MulBinary(a, b):
    if len(a) < len(b):  # 以長的二進位制字串為遍歷起點
        temp = a
        a = b
        b = temp
    a = a[::-1]  # 倒序二進位制字串
    b = b[::-1]
    Add = ""
    index = 0

    for num in b:  # 遍歷
        new_binary = ""
        flag = 0
        for x in a:
            for i in range(index):
                if flag == 0:
                    new_binary = new_binary + "0"
                    flag = 1
            new_binary = new_binary + str((int(num) & int(x)))

        index = index + 1
        new_binary = new_binary[::-1]

        if index == 1:
            Add = new_binary
        else:
            Add = addBinary(Add, new_binary)  # 二進位制加法運算

    return Add  # 倒序輸出


def SudBinary(a, b):
    if len(a) < len(b):  # 以長的二進位制字串為遍歷起點
        temp = a
        a = b
        b = temp
    a = a[::-1]  # 倒序二進位制字串
    b = b[::-1]
    extra = 0  # 退位
    new_binary = ""
    for index, num in enumerate(a):  # 遍歷
        if index > len(b) - 1:  # 判斷短的二進位制字串是否越界
            b_sum = 0
        else:
            b_sum = int(b[index])
        new_binary = new_binary + str((int(num) - b_sum - extra) % 2)  # 二進位制減法運算
        if int(num) - b_sum - extra < 0:  # 是否退位
            extra = 1
        else:
            extra = 0

    if new_binary[-1] == 0:
        del new_binary[-1]

    return new_binary[::-1]  # 倒序輸出


def beBin(a):
    # print(a)
    p = bin(a)
    # print(p)
    p = p.replace("0b", '')
    return p


def AddOct(a, b):

    p = beBin(int(a, 8))
    q = beBin(int(b, 8))
    t = oct(int(addBinary(p, q), 2))
    return t


def AddHex(a, b):

    p = beBin(int(a, 16))
    q = beBin(int(b, 16))
    t = hex(int(addBinary(p, q), 2))
    return t


def MulOct(a, b):

    p = beBin(int(a, 8))
    q = beBin(int(b, 8))
    t = oct(int(MulBinary(p, q), 2))
    return t


def MulHex(a, b):

    p = beBin(int(a, 16))
    q = beBin(int(b, 16))
    t = hex(int(MulBinary(p, q), 2))
    return t


def SudOct(a, b):

    p = beBin(int(a, 8))
    q = beBin(int(b, 8))
    t = oct(int(SudBinary(p, q), 2))
    return t


def SudHex(a, b):

    p = beBin(int(a, 16))
    q = beBin(int(b, 16))
    t = hex(int(SudBinary(p, q), 2))
    return t


a =input("請輸入第一個二進位制數: ")
b =input("請輸入第二個二進位制數: ")
print("a+b= "+addBinary(a, b))
print("a*b="+MulBinary(a, b))
print("a-b= "+SudBinary(a, b))

a = '0o'+input("請輸入第一個八進位制數: ")
b = '0o'+input("請輸入第二個八進位制數: ")
print("輸出是八進位制的:")
print("a+b= "+AddOct(a, b))
print("a*b="+MulOct(a, b))
print("a-b= "+SudOct(a, b))

a = '0x'+input("請輸入第一個十六進位制數: ")
b = '0x'+input("請輸入第二個十六進位制數: ")
print("輸出是十六進位制的:")
print("a+b= "+AddHex(a, b))
print("a*b="+MulHex(a, b))
print("a-b= "+SudHex(a, b))