在计算机科学中,我们通常把数据类型划分成两类:基本数据类型和复杂数据类型。对于基本数据类型,Python中已经为我们提供了丰富的支持,但是对于大数运算(即超出基本数据类型所能表示的数字范围),我们需要使用复杂数据类型来实现。本文将着重探讨如何自己实现Python中的大数运算,以及如何实现大数运算的重要工具——large函数。
为什么需要大数运算?
在介绍大数运算之前,我们先来看一个问题:计算100!(即100的阶乘,即100×99×98×...×1的值)。在使用基本数据类型的情况下,由于100!的值超出了基本数据类型所能表示的范围,因此我们需要使用复杂数据类型来实现。
为了更好的理解大数运算的必要性,我们比较一下两组数据:
1. [9223372036854775807, 9223372036854775806, ..., 1](共有9223372036854775807个数字)
2. [18446744073709551615]
第一组数据表示的是一个超级大的数,由于它比第二组数据还要大得多,因此我们需要运用大数运算的技术来完成它的加减乘除等运算。
Python中的大数运算
Python中提供了一个专门用于大数运算的模块——Decimal,使用该模块,我们可以进行浮点数计算和限精度计算,其中限精度计算就是大数运算。除此之外,Python中也提供了另一个用于大数运算的模块——Fraction,它可以进行有理数的运算,同样支持大数运算。
使用Decimal模块实现大数运算
首先,我们需要对待运算的数字进行初始化处理,把它们转换为Decimal类型。这样就可以在Python中对其进行精准的运算。以下代码示例为将两个字符串进行大数运算:
```python
from decimal import Decimal
a = Decimal('10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
b = Decimal('10000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
c = a + b
print(c)
```
输出结果为:
```
1.000000000000000000000000000000000000000000000000001e+115
```
这里有一个小技巧,就是可以使用字符串形式来初始化Decimal类型,这样是为了避免在使用十进制浮点数时出现精度误差。
以上代码展示了如何使用Decimal模块进行大数加法运算,其他基本运算相对应的方法也是类似的,我们不再一一介绍。
使用Fraction模块实现大数运算
在使用Fraction模块时,我们首先需要用Fractions()函数初始化分数,之后就可以进行分数的正常运算了。以下代码示例为将两个字符串进行大数运算并打印结果:
```python
from fractions import Fraction
a = Fraction('10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
b = Fraction('10000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
c = a + b
print(c)
```
输出结果为:
```
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000
```
这里同样采取了字符串初始化的方式。
自己实现大数运算
通过以上介绍,我们了解了Python中的两个常用的大数运算工具——Decimal模块和Fraction模块,它们足以满足我们的大部分需求。但是如果我们想进一步掌握大数运算的原理和实现方法,就必须自己实现一个大数运算库。
实现自己的large函数
以下是自己实现的large函数,可以进行加、减、乘、除、幂等基本运算:
```python
# 大数运算函数
def large(a, b, op):
# a,b为大数字符串,op为运算符(+,-,*,/,**)
# 将字符串转换为字典(每个数字为一个元素,从高位到低位存储)
a = [int(i) for i in a][::-1]
b = [int(i) for i in b][::-1]
index = 0
result = [0] * (len(a) + len(b))
# 加法
if op == '+':
while index < len(a) or index < len(b):
sum = (a[index] if index < len(a) else 0) + (b[index] if index < len(b) else 0) + result[index]
result[index] = sum % 10
if sum >= 10:
result[index + 1] += 1
index += 1
# 减法
if op == '-':
if a == b:
return '0'
if len(a) > len(b):
sign = True
elif len(a) < len(b):
sign = False
a, b = b, a
else:
for i in range(len(a) - 1, -1, -1):
if a[i] > b[i]:
break
elif a[i] < b[i]:
sign = False
a, b = b, a
break
else:
return '0'
sign = True
for i in range(len(a)):
result[i] = a[i] - (b[i] if i < len(b) else 0) - result[i]
if result[i] < 0:
result[i] += 10
result[i + 1] -= 1
# 乘法
if op == '*':
for i in range(len(a)):
for j in range(len(b)):
result[index + i + j] += a[i] * b[j]
for i in range(len(result) - 1):
result[i + 1] += result[i] // 10
result[i] %= 10
# 除法
if op == '/':
quotient = [0] * len(a)
for i in range(len(a) - 1, -1, -1):
remainder = 0
dividend = remainder * 10 + a[i]
while dividend >= b[-1]:
dividend -= b[-1]
remainder += 1
quotient[i] = remainder
for j in range(len(b) - 1, -1, -1):
temp = a[i - len(b) + 1:i + 1]
temp = [(0 if i < 0 else i) for i in temp]
temp = [m * quotient[i] for m in temp][::-1]
k = len(result) - (i - len(b) + 1) - (len(b) - j)
for s in range(len(temp)):
result[k + s] += temp[s]
for s in range(len(result) - 1):
result[s + 1] += result[s] // 10
result[s] %= 10
if i >= len(b) and a[i - len(b)] == 0:
b.insert(0, 0)
# 幂
if op == '**':
base = [int(i) for i in a][::-1]
exp = int(b)
result = [1]
while exp:
if exp & 1:
result = large(result, base, '*')
base = large(base, base, '*')
exp >>= 1
# 将字典元素转换为字符串,并去掉前导0
result = result[::-1]
if result[0] == 0:
result = result[1:]
result = ''.join([str(i) for i in result])
return result
```
以上代码中的large函数使用了一些常规思路,例如如果数据中存在负数,我们就将数据转化为无符号状态进行运算。大数除法的实现较为复杂,我们使用了试除法来实现大数的整数除法。
使用large函数进行大数运算
我们可以使用如下方式,使用large函数进行大数运算:
```python
# 调用large函数进行大数加法运算
a = '999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999'
b = '1'
c = large(a, b, '+')
print(c)
# 调用large函数进行大数减法运算
a = '999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999'
b = '1'
c = large(a, b, '-')
print(c)
# 调用large函数进行大数乘法运算
a = '999999999999999999999999999999999999999999'
b = '999999999999999999999999999999999999999999'
c = large(a, b, '*')
print(c)
# 调用large函数进行大数除法运算
a = '100000000000000000000000000000000000000000000000000000000000000000000000000000000000'
b = '999999999999999999999999999999999999999999'
c = large(a, b, '/')
print(c)
# 调用large函数进行大数幂运算
a = '3'
b = '5'
c = large(a, b, '**')
print(c)
```
这里我们首先定义了三个字符型变量,接着调用large函数进行加、减、乘、除、幂等基本运算,并打印出结果。
总结
本文主要介绍了Python中的大数运算,并通过调用Python提供的Decimal模块和Fraction模块,为大家展示了如何进行大数计算。另外,我们也通过实现large函数,为大家提供了一种自己实现大数计算的示例。大数计算虽然较为复杂,但通过学习本文的内容,你应该可以更好的理解大数计算的原理和实现方法。