在一个C程序中,我尝试了以下操作(只是为了检查行为)
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf("%d ,%d ,%d", x, y, z);
在gcc中输出为(2,-2,-2)我以为每次都会有积极的结果。模量可以是负的吗?有人能解释一下这种行为吗?
在一个C程序中,我尝试了以下操作(只是为了检查行为)
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf("%d ,%d ,%d", x, y, z);
在gcc中输出为(2,-2,-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的因数)
要进一步阅读,请参阅数学中的等价类。
其他回答
模运算的结果取决于分子的符号,因此y和z都是-2
这是参考资料
http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html
整数的除法 介绍整数除法的函数。 这些函数在GNU C库中是多余的,因为在GNU C中 '/'运算符总是四舍五入到零。但是在其他C中 实现中,'/'可以用不同的负参数四舍五入。 Div和ldiv很有用,因为它们指定了如何舍入 商:趋于零。余数的符号和 分子。
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时才会发生这种情况
模算子给出余数。 c中的模算子通常取分子的符号
X = 5%(-3)这里分子是正的,所以结果是2 Y =(-5) %(3)分子为负,结果为-2 Z =(-5) %(-3)这里分子是负的所以结果是-2
此外,模(余数)运算符只能用于整型,不能用于浮点数。
我认为没有必要检查数字是否为负。
求正模的一个简单函数是这个-
编辑:假设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附近),那么你应该分别处理正的和负的情况,在这里的其他答案中描述。
我认为在抽象算术中定义mod会更有用;不是作为一个运算,而是作为一个完全不同的算术类别,有不同的元素和不同的运算符。这意味着mod 3中的加法与“正常的”加法不同;这是;整数加法。
所以当你这样做的时候:
5 % -3
你试图将整数5映射到mod -3集合中的一个元素。这些是mod -3的元素:
{ 0, -2, -1 }
So:
0 => 0, 1 => -2, 2 => -1, 3 => 0, 4 => -2, 5 => -1
假设你因为某种原因不得不熬夜30个小时,那一天你还剩下几个小时?30 mod -24。
但是C语言实现的不是余,而是余数。不管怎样,关键是返回负号是有意义的。