Python 取模运算(%)
取模运算符 % 表示「除法后的余数」。在 Python 中,整型与浮点型都支持 %(与「模块 module」拼写相近,注意别混淆)。
语法:a % b —— a 为被除数,b 为除数,结果为 a 除以 b 的余数。
- 若
a、b均为整数,结果一般为整数(在类型提升规则下也可能为浮点,见下文)。 - 若任一方为浮点数,结果通常为浮点数。
算术运算符总览见 运算符。
整数取模
shell
>>> 10 % 3
1
>>> 2 % 2
0
>>> 17 % 5
2浮点数参与取模
shell
>>> 9 % 3.0
0.0
>>> 10 % 3.0
1.0与用户输入结合
注意:input() 返回的是字符串,需用 int() / float() 转成数字后再做 %。第二个提示语应写「第二个数」,避免与第一个重复。
python
x = input("请输入第一个数:\n")
fx = float(x)
y = input("请输入第二个数:\n")
fy = float(y)
print(f"{x} % {y} = {fx % fy}")若用 float(),输出里余数可能是 1.0 而不是 1,这是类型所致。更多见 input() 函数。
除数为 0:ZeroDivisionError
除数为 0 时,% 与 / 一样会抛出 ZeroDivisionError,可用 try / except 处理:
python
a = 10.5
b = 0
try:
print(f"{a} % {b} = {a % b}")
except ZeroDivisionError:
print("除数不能为 0")负数与 % 的符号规则(易混点)
Python 中 a % b 的结果与 除数 b 的符号一致(或与 b 同号;若余数为 0 则为 0):
shell
>>> -5 % 3 # 除数为正 → 余数非负
1
>>> 5 % -3 # 除数为负 → 余数非正
-1
>>> -10 % 3
2这与部分语言「余数与被除数同号」的约定不同,写跨语言算法时要特别留意。
若需要与 C 语言 中浮点取模更接近的行为(余数符号与被除数 a 一致),对浮点数可使用 math.fmod:
shell
>>> import math
>>> math.fmod(-5, 3)
-2.0
>>> math.fmod(5, -3)
2.0
>>> math.fmod(-10, 3)
-1.0详见下文 math.fmod 小节。
math.fmod 与 % 的差异(浮点)
a % b:遵循 Python 的取模定义,结果符号与b相关;对浮点仍可能受二进制精度影响。math.fmod(a, b):更接近 C 的fmod,返回a - n*b且与a同号;文档推荐用于浮点取模场景。
官方说明见 math.fmod。
通过 __mod__ 重载 %
自定义类可实现 __mod__,使 % 作用于该类型的实例(与面向对象、运算符重载相关,详见 运算符重载)。
python
class Data:
def __init__(self, i):
self.id = i
def __mod__(self, other):
print("modulo function called")
return self.id % other.id
def __str__(self):
return f"Data[{self.id}]"
d1 = Data(10)
d2 = Data(3)
print(f"{d1} % {d2} = {d1 % d2}")输出:
text
modulo function called
Data[10] % Data[3] = 1浮点误差与取模
二进制浮点数往往无法精确表示十进制小数,因此 % 的结果可能出现「肉眼以为该为 0」的残差:
shell
>>> 9.6 % 3.2
3.1999999999999993
>>> 9.6 == 3.2 * 3
False需要精确十进制运算时,可使用标准库 decimal.Decimal,或比较前用 round()、允许误差的差值判断等(视业务而定):
shell
>>> round(9.6, 3) == round(3.2 * 3, 3)
True小结
a % b:余数;b == 0报错。- 负数:Python
%的结果与b的符号一致;math.fmod与a的符号一致(浮点、偏 C 语义)。 - 浮点:注意二进制表示误差;关键场景考虑
decimal或合理舍入/比较策略。