负数的模运算

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。如果我们插入 ab,我们得到 -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