長整數運算

2020-10-13 12:00:19

正整數運算

  這次,我們加法採用對位相加,也就是兩個長整數對應位上的數位相加,之後再計算進位,最後得出結果的方法。

正整數相加-對位相加

例如數位
被加數1111
加數99999

  先將數位串分割為獨立的數位,再對位相加。

···十萬萬位千位百位十位個位
被加數001111
+++++++
加數099999
結果0910101010

  之後是處理進位。

···十萬萬位千位百位十位個位
個位進位09101010+1←0
十位進位091010+1←10
百位進位0910+1←110
千位進位010←1110
萬位進位0+1←01110
最終結果101110

  上程式碼:

# 大正整數相加
def SUM():
    # 分割數位字串
    num1 = list(input())
    num2 = list(input())

    # 分割字串從右對齊逐個相加存入temp
    len1 = len(num1)
    len2 = len(num2)
    count = max(len1, len2)
    index = 0
    temp = [0 for i in range(count+1)]
    if len1 > len2:  # 哪個數更長的操作
        index = len2-1
    else:
        index = len1-1
    for i in range(count, 0, -1):
        if len1 > len2:
            if index >= 0:
                temp[i] += int(num2[index])
                index -= 1
            temp[i] += int(num1[i-1])
        else:
            if index >= 0:
                temp[i] += int(num1[index])
                index -= 1
            temp[i] += int(num2[i-1])

    # 判斷是否有進位
    for i in range(count, -1, -1):
        if temp[i] > 9:
            temp[i] = temp[i] % 10
            temp[i-1] += 1
        temp[i] = str(temp[i])
    # 無進位,刪掉擡頭0
    if temp[0] == '0':
        temp.pop(0)
        count -= 1

    # 大整數連線起來
    Sum = ''
    for i in range(count+1):
        Sum += temp[i]
    print(Sum)

  加數和被加數倒過來也一樣,但是涉及到誰的位數更大一些,程式碼上需要判斷一下,因為程式碼中儲存對位相加結果的變數temp[]的長度是按最長的整數的長度而定的(多一位,因為可能會進位)。

正整數相減-對位相減

  整數相減不同於相加,被減數和減數不能隨意顛倒位置,但是我們仍可以使用對位相減的方法,只是需要限制。
  減法,實質上是求兩個數的距離,例如:

9999 − 91111 = − ( 91111 − 9999 ) 9999 - 91111 = - ( 91111 - 9999 ) 999991111=(911119999)

  那麼這樣的話,我們可以將更大的數位始終作為被減數,只需要在結果判斷是否新增負號即可。

例如數位
被減數9999
減數91111

  同加法,分割字元,但是減數更大,將減數變成被減數,被減數變為減數,結果添負:

···符號萬位千位百位十位個位
被減數-91111
------
減數-9999
結果-9-8-8-8-8

  之後是處理借位。

···符號萬位千位百位十位個位
結果-9-8-8-8-1→10-8
結果-9-8-8-1→10-92
結果-9-8-1→10-912
結果-9-1→10-9112
最終結果-81112

  那麼問題來了! 能不能小的減大的呢,這不省掉了判斷大小那一步嗎?

  我們試一試:

···符號萬位千位百位十位個位
被減數+9999
------
減數+91111
結果+-98888

  之後是處理借位,這裡我發現一個規律,就是最高位是負的,需要向更高位借位,但是沒有更高位了,頭禿。

  但是,我發現將結果每位都取負,然後結果符號也取負。

  結果如下:

···符號萬位千位百位十位個位
結果-9-8-8-8-8
最終結果-81112

  頭禿,是可以的。但是也OK,程式碼也被簡化了,上程式碼:

# 大正整數相減
def SUB():
    # 分割數位字串
    num1 = list(input())
    num2 = list(input())

    # 分割字串從右對齊長(大)減短(小)存入temp
    len1 = len(num1)
    len2 = len(num2)
    count = max(len1, len2)
    index = 0
    symbol = 0
    temp = [0 for i in range(count)]
    if len1 > len2:
        index = len2 - 1
    else:
        index = len1 - 1
    for i in range(count-1, -1, -1):
        if len1 > len2:
            if index >= 0:
                temp[i] -= int(num2[index])
                index -= 1
            temp[i] += int(num1[i])
        else:
            if index >= 0:
                temp[i] += int(num1[index])
                index -= 1
            temp[i] -= int(num2[i])
    
    # 判斷結果是否有0字首,有則去除
    while temp[0] == 0:
        if len(temp) == 1 and temp[0] == 0:
            print(0)
            return
        temp.pop(0)
        count -= 1

    # 符號置換,使最高位能夠借位給低位
    if temp[0] < 0:
        symbol = 1
        for i in range(count):
            temp[i] = temp[i] * (-1)

    #判斷借位
    for i in range(count-1, -1, -1):
        if temp[i] < 0:
            temp[i] += 10
            temp[i-1] -= 1

    #新增結果符號
    if symbol == 1:
        sub = "-"
        for i in range(count):
            sub += str(temp[i])
        print(sub)
    else:
        sub = ""
        for i in range(count):
            sub += str(temp[i])
        print(sub)

整數運算

整理中~