2. 算术操作数详解:整数、浮点数、复数在算术运算中的表现

聊到 Python 的算术运算,很多人觉得不就是加减乘除嘛,有啥好讲的?

嗯,我刚开始也是这么想的。直到有一次在金融项目里,因为浮点数精度问题导致对账差了 0.01 元,查了整整一个下午。从那以后,我对 Python 的数值类型就再也不敢马虎了。

说白了,整数、浮点数、复数这三种类型,在算术运算中的行为差异很大。不理解这些差异,写出来的代码就可能藏着坑。

2.1 整数:Python 的「大胃王」

Python 的整数和其他语言不太一样。C 语言里 int 有范围限制,超出就溢出。但 Python 的整数是 任意精度 的。

核心特性:Python 3 中 int 可以无限大,只受内存限制。

# 你能想象这么大的整数吗?
big_num = 10 ** 100
print(big_num)
# 输出:10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

# 再大一点也没问题
huge_num = 2 ** 1000
print(len(str(huge_num)))  # 302 位数字

我个人习惯在做大数计算时,直接用 Python 的 int,省心。不像 Java 还得用 BigInteger。

小技巧:整数除法用 // 会向下取整。注意是向下,不是向零取整。负数时容易搞错。

print(7 // 3)   # 2
print(-7 // 3)  # -3,不是 -2!
# 因为 -7/3 ≈ -2.33,向下取整得到 -3

2.2 浮点数:精度是个老话题

浮点数在计算机里是用二进制表示的。你想想看,0.1 在二进制里是个无限循环小数。所以 0.1 + 0.2 不等于 0.3,这是所有语言的通病。

print(0.1 + 0.2)  # 0.30000000000000004
print(0.1 + 0.2 == 0.3)  # False

我在项目中遇到过最典型的场景:累计金额时,每次加 0.01,加 100 次,结果不是 1.0。财务那边直接炸了。

避坑指南:千万不要用浮点数做精确的金额计算。我曾经吃过这个亏,后来全改成 Decimal 了。

Python 的浮点数遵循 IEEE 754 标准,双精度 64 位。有效数字大约 15-17 位。

操作 示例 结果 说明
加法 0.1 + 0.2 0.30000000000000004 精度误差
乘法 0.1 * 3 0.30000000000000004 同样有误差
比较 0.1 + 0.2 == 0.3 False 别直接比较
取整 round(2.675, 2) 2.67 银行家舍入

建议:比较浮点数时用 math.isclose(),或者自己设个误差范围。

import math
print(math.isclose(0.1 + 0.2, 0.3))  # True

# 或者手动设阈值
eps = 1e-9
print(abs(0.1 + 0.2 - 0.3) < eps)  # True

2.3 复数:Python 的隐藏技能

说实话,复数在日常开发中用得不多。但做科学计算、信号处理时,它就是主角了。

Python 用 j 表示虚数单位,注意不是 i。

# 定义复数
z1 = 3 + 4j
z2 = 1 - 2j

# 基本运算
print(z1 + z2)  # (4+2j)
print(z1 * z2)  # (11-2j)
print(z1 / z2)  # (-1+2j)

# 获取实部和虚部
print(z1.real)  # 3.0
print(z1.imag)  # 4.0

我记得有一次做音频频谱分析,用复数表示频域信号,Python 的 cmath 模块帮了大忙。

注意:复数不能直接比较大小。你写 3+4j > 1+2j 会报错。要比较的话,比较模长。

z1 = 3 + 4j
z2 = 1 + 2j
# print(z1 > z2)  # TypeError: '>' not supported between instances of 'complex' and 'complex'

# 正确做法:比较模长
print(abs(z1) > abs(z2))  # True

2.4 类型转换:混合运算时的规则

不同类型的数值在一起运算时,Python 会自动做类型提升。规则很简单:朝着更「宽」的类型转换。

宽度顺序:int → float → complex

# int + float → float
print(type(3 + 0.5))  # <class 'float'>

# int + complex → complex
print(type(3 + 4j))  # <class 'complex'>

# float + complex → complex
print(type(3.0 + 4j))  # <class 'complex'>

你想想看,如果 int 和 float 运算结果还是 int,那 3 / 2 就变成 1 了,这显然不合理。Python 3 在这方面做得比 Python 2 好多了。

注意:Python 3 中 / 永远返回浮点数。想要整数结果用 //。

2.5 知识结构图

下面这张图帮你理清三种数值类型在算术运算中的关系:

Python 算术操作数体系 整数 (int) 浮点数 (float) 复数 (complex) 任意精度 IEEE 754 双精度 实部 + 虚部 自动提升 自动提升 类型提升规则 int → float → complex(朝着更宽的类型转换) 算术运算:+ - * / // % **

2.6 实战建议

  • 整数运算:放心用,不会溢出。但注意 // 的向下取整行为。
  • 浮点运算:别做精确比较。用 math.isclose() 或设阈值。
  • 复数运算:用 cmath 模块处理数学函数,别直接比较大小。
  • 混合运算:了解类型提升规则,避免意外结果。

个人习惯:我写代码时,只要涉及金额,一律用 Decimal。涉及科学计算,用 numpy 的浮点类型。纯逻辑计数,用 int。各司其职,少踩坑。