Python长整数运算
- 正整数运算
-
- 正整数相加-对位相加
- 正整数相减-对位相减
- 整数运算
正整数运算
这次,我们加法采用对位相加,也就是两个长整数对应位上的数字相加,之后再计算进位,最后得出结果的方法。
正整数相加-对位相加
例如 | 数字 |
---|---|
被加数 | 1111 |
加数 | 99999 |
先将数字串分割为独立的数字,再对位相加。
··· | 十万 | 万位 | 千位 | 百位 | 十位 | 个位 |
---|---|---|---|---|---|---|
被加数 | 0 | 0 | 1 | 1 | 1 | 1 |
+ | + | + | + | + | + | + |
加数 | 0 | 9 | 9 | 9 | 9 | 9 |
结果 | 0 | 9 | 10 | 10 | 10 | 10 |
之后是处理进位。
··· | 十万 | 万位 | 千位 | 百位 | 十位 | 个位 |
---|---|---|---|---|---|---|
个位进位 | 0 | 9 | 10 | 10 | 10+1 | ←0 |
十位进位 | 0 | 9 | 10 | 10+1 | ←1 | 0 |
百位进位 | 0 | 9 | 10+1 | ←1 | 1 | 0 |
千位进位 | 0 | 10 | ←1 | 1 | 1 | 0 |
万位进位 | 0+1 | ←0 | 1 | 1 | 1 | 0 |
最终结果 | 1 | 0 | 1 | 1 | 1 | 0 |
上代码:
# 大正整数相加
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 ) 9999−91111=−(91111−9999)
那么这样的话,我们可以将更大的数字始终作为被减数,只需要在结果判断是否添加负号即可。
例如 | 数字 |
---|---|
被减数 | 9999 |
减数 | 91111 |
同加法,分割字符,但是减数更大,将减数变成被减数,被减数变为减数,结果添负:
··· | 符号 | 万位 | 千位 | 百位 | 十位 | 个位 |
---|---|---|---|---|---|---|
被减数 | - | 9 | 1 | 1 | 1 | 1 |
- | - | - | - | - | - | |
减数 | - | 9 | 9 | 9 | 9 | |
结果 | - | 9 | -8 | -8 | -8 | -8 |
之后是处理借位。
··· | 符号 | 万位 | 千位 | 百位 | 十位 | 个位 |
---|---|---|---|---|---|---|
结果 | - | 9 | -8 | -8 | -8-1→ | 10-8 |
结果 | - | 9 | -8 | -8-1→ | 10-9 | 2 |
结果 | - | 9 | -8-1→ | 10-9 | 1 | 2 |
结果 | - | 9-1→ | 10-9 | 1 | 1 | 2 |
最终结果 | - | 8 | 1 | 1 | 1 | 2 |
那么问题来了! 能不能小的减大的呢,这不省掉了判断大小那一步吗?
我们试一试:
··· | 符号 | 万位 | 千位 | 百位 | 十位 | 个位 |
---|---|---|---|---|---|---|
被减数 | + | 9 | 9 | 9 | 9 | |
- | - | - | - | - | - | |
减数 | + | 9 | 1 | 1 | 1 | 1 |
结果 | + | -9 | 8 | 8 | 8 | 8 |
之后是处理借位,这里我发现一个规律,就是最高位是负的,需要向更高位借位,但是没有更高位了,头秃。
但是,我发现将结果每位都取负,然后结果符号也取负。
结果如下:
··· | 符号 | 万位 | 千位 | 百位 | 十位 | 个位 |
---|---|---|---|---|---|---|
结果 | - | 9 | -8 | -8 | -8 | -8 |
最终结果 | - | 8 | 1 | 1 | 1 | 2 |
头秃,是可以的。但是也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)
整数运算
整理中~