负数求余结果不唯一,取决于规则:数学中余数非负,Python向负无穷取整得余数同被除数符号,C语言向零取整得余数同被除数符号。

负数求余没有唯一答案,关键看采用哪套规则——数学定义、编程语言实现,还是实际工程需求。不同场景下,“余数”可能正、可能负,但必须满足基本等式:a = b × q + r,其中 q 是整数商,r 是余数,且 |r| (除数绝对值严格大于余数绝对值)。
一、数学上最常用的“非负余数”规则
中小学及数论中普遍要求:余数 ≥ 0,且小于除数的绝对值。即对任意整数 a 和非零整数 b,存在唯一整数 q 和 r,使得:
- a = b × q + r
- 0 ≤ r
这个 r 就叫“最小非负剩余”,也称“模意义下的标准余数”。例如:
- −7 ÷ 3 → 找最大的 q 使 3×q ≤ −7,即 q = −3,那么 r = −7 − 3×(−3) = 2(因为 0 ≤ 2
- −16 ÷ 7 → q = −3,r = −16 − 7×(−3) = 5(0 ≤ 5
- 10 ÷ (−3) → 注意:按此规则,除数是 −3,|b| = 3,所以仍要求 0 ≤ r
二、Python 的取余行为(向负无穷取整)
Python 中 % 是“取模运算符”,其商 // 向负无穷舍入(floor division),因此余数符号与除数一致:
- −10 % 3 → 商为 −4(因为 −10//3 = −4),r = −10 − 3×(−4) = 2(余数 > 0,同除数符号)
- 10 % −3 → 商为 −4(10//−3 = −4),r = 10 − (−3)×(−4) = −2(余数
- −10 % −3 → 商为 4(−10//−3 = 3?错,实际是 3?再算:−10 ÷ −3 ≈ 3.33,向下取整为 3;r = −10 − (−3)×3 = −1 → 符合 −3
一句话记住:Python 的 a % b 结果,总是与 b 同号(或为 0),且满足 0 ≤ r 0)或 b
三、C/C++、Java 等语言的“求余”行为(向零取整)
这些语言中 % 是“余数运算符”,商向零截断(truncation),余数符号与被除数一致:
- −7 % 3 → 商为 −2(截去小数),r = −7 − 3×(−2) = −1(余数
- 7 % −3 → 商为 −2,r = 7 − (−3)×(−2) = 1(余数 > 0,同被除数)
- −7 % −3 → 商为 2,r = −7 − (−3)×2 = −1(余数
特点是:a % b 的符号永远和 a 一样(除非为 0),且 |r|
四、怎么选?实用建议
日常计算或数学建模,优先用非负余数规则(0 ≤ r
- 需要循环索引、哈希取槽、日期偏移等?用 Python 风格更安全(如
index % len(arr)永远不越界) - 做底层协议解析、与 C 库交互?注意 C 风格余数可能为负,需手动修正:
r = (a % b + abs(b)) % abs(b) - 判断“被 3 除余 2 的所有整数”?集合是 {…, −7, −4, −1, 2, 5, 8, …} = {3k + 2 ∣ k ∈ ℤ},这里隐含采用非负余数定义,−1 不算(因 −1 mod 3 = 2 才对),而 −4 = 3×(−2) + 2,余数确实是 2
本质上,负数求余不是算错,而是“定义不同”。看清上下文,明确你想要的是余数的符号倾向、范围约束,再选择对应公式或语言特性即可。

















