在一个C程序中,我尝试了以下操作(只是为了检查行为)

 x = 5 % (-3);
 y = (-5) % (3);
 z = (-5) % (-3); 

printf("%d ,%d ,%d", x, y, z); 

在gcc中输出为(2,-2,-2)我以为每次都会有积极的结果。模量可以是负的吗?有人能解释一下这种行为吗?


当前回答

C99要求当a/b是可表示的时:

(a/b) * b + a%b等于a

从逻辑上讲,这是有道理的。对吧?

让我们看看这会导致什么:


例A. 5/(-3) = -1

=> (-1) * (-3) + 5%(-3) = 5

这只能在5%(-3)= 2时发生。


例b (-5)/3 = -1

=> (-1) * 3 + (-5)%3 = -5

只有当(-5)%3为-2时才会发生这种情况

其他回答

在数学中,这些惯例的起源,没有断言模算术应该产生一个正的结果。

Eg.

1 mod 5 = 1,但也可以等于-4。也就是说,1/5从0得到余数1或从5得到余数-4。(都是5的因数)

同样的, -1 mod 5 = -1,它也可以等于4。也就是说,-1/5从0得到余数-1或从-5得到余数4。(都是5的因数)

要进一步阅读,请参阅数学中的等价类。

看来问题不在现场操作。

int mod(int m, float n)
{  
  return m - floor(m/n)*n;
}

我认为没有必要检查数字是否为负。

求正模的一个简单函数是这个-

编辑:假设N > 0和N + N - 1 <= INT_MAX

int modulo(int x,int N){
    return (x % N + N) %N;
}

这对x的正负都成立。

原始p.s.:也正如@chux指出的那样,如果你的x和N可能分别达到INT_MAX-1和INT_MAX,只需将int替换为long long int。

如果它们也越过了long long的限制(即在LLONG_MAX附近),那么你应该分别处理正的和负的情况,在这里的其他答案中描述。

根据C99规格:a == (a / b) * b + a % b

我们可以写一个函数来计算(a % b) == a - (a / b) * b!

int remainder(int a, int b)
{
    return a - (a / b) * b;
}

对于模运算,我们可以有以下函数(假设b > 0)

int mod(int a, int b)
{
    int r = a % b;
    return r < 0 ? r + b : r;
}

我的结论是C中的a % b是一个余数运算,而不是一个模运算。

C99要求当a/b是可表示的时:

(a/b) * b + a%b等于a

从逻辑上讲,这是有道理的。对吧?

让我们看看这会导致什么:


例A. 5/(-3) = -1

=> (-1) * (-3) + 5%(-3) = 5

这只能在5%(-3)= 2时发生。


例b (-5)/3 = -1

=> (-1) * 3 + (-5)%3 = -5

只有当(-5)%3为-2时才会发生这种情况