负数的模运算
modulo operation on negative numbers
模运算 a%b
return 是 a/b
的余数,但对于负数它不会这样做。
#include <stdio.h>
int main(void) {
int n=-4;
printf("%d\n",n%3);
return 0;
}
它应该 return 2 因为 3*(-2)=-6 刚好小于 -4 并且是 3 的倍数,但输出是 -1。
为什么它对待 (-a) mod b
与 -(a mod b)
相同
一般来说,取模和除法应满足方程
b * (a/b) + a%b == a
对于正数,很明显这意味着a%b
必须是正数。但如果 a/b
为负数,则结果将四舍五入为零。
所以以a = -4, b = 3为例,我们知道a/b = -1.3333,向零四舍五入变为 a/b == -1
。从上面的方程式,我们有 b * (-1) + a%b == a
。如果我们插入 a
和 b
,我们得到 -3 + a%b == -4
,我们看到 a%b
必须是 -1。
你的痛苦源于拥抱 %
是 "modulo" 运算符的错觉。事实上,它是一个余数运算符(C11 §6.5.5):
The result of the /
operator is the quotient from the division of
the first operand by the second; the result of the %
operator is the
remainder
拒绝幻想接受真相,经营者的行为就会变得清晰(同上):
If the quotient a/b
is representable, the expression (a/b)*b + a%b
shall equal a
在您的例子中,a/b
是 -4/3
,即 -1
,因此可以表示。所以 a%b
满足:
(a/b)*b + a%b = a
(-1)*3 + a%b = -4
-3 + a%b = -4
a%b = -1
模运算 a%b
return 是 a/b
的余数,但对于负数它不会这样做。
#include <stdio.h>
int main(void) {
int n=-4;
printf("%d\n",n%3);
return 0;
}
它应该 return 2 因为 3*(-2)=-6 刚好小于 -4 并且是 3 的倍数,但输出是 -1。
为什么它对待 (-a) mod b
与 -(a mod b)
一般来说,取模和除法应满足方程
b * (a/b) + a%b == a
对于正数,很明显这意味着a%b
必须是正数。但如果 a/b
为负数,则结果将四舍五入为零。
所以以a = -4, b = 3为例,我们知道a/b = -1.3333,向零四舍五入变为 a/b == -1
。从上面的方程式,我们有 b * (-1) + a%b == a
。如果我们插入 a
和 b
,我们得到 -3 + a%b == -4
,我们看到 a%b
必须是 -1。
你的痛苦源于拥抱 %
是 "modulo" 运算符的错觉。事实上,它是一个余数运算符(C11 §6.5.5):
The result of the
/
operator is the quotient from the division of the first operand by the second; the result of the%
operator is the remainder
拒绝幻想接受真相,经营者的行为就会变得清晰(同上):
If the quotient
a/b
is representable, the expression(a/b)*b + a%b
shall equala
在您的例子中,a/b
是 -4/3
,即 -1
,因此可以表示。所以 a%b
满足:
(a/b)*b + a%b = a
(-1)*3 + a%b = -4
-3 + a%b = -4
a%b = -1