Skip to content

Python 取模运算(%

取模运算符 % 表示「除法后的余数」。在 Python 中,整型与浮点型都支持 %(与「模块 module」拼写相近,注意别混淆)。

语法:a % b —— a 为被除数,b 为除数,结果为 a 除以 b 的余数

  • ab 均为整数,结果一般为整数(在类型提升规则下也可能为浮点,见下文)。
  • 任一方为浮点数,结果通常为浮点数。

算术运算符总览见 运算符

整数取模

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.fmoda 的符号一致(浮点、偏 C 语义)。
  • 浮点:注意二进制表示误差;关键场景考虑 decimal 或合理舍入/比较策略。

参考