在一个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)我以为每次都会有积极的结果。模量可以是负的吗?有人能解释一下这种行为吗?
当前回答
看来问题不在现场操作。
int mod(int m, float n)
{
return m - floor(m/n)*n;
}
其他回答
看来问题不在现场操作。
int mod(int m, float n)
{
return m - floor(m/n)*n;
}
模量可以是负的吗?
%可以是负数,因为它是余数运算符,是除法后的余数,而不是欧几里得除法后的余数。由于C99的结果可能是0,负或正。
// a % b
7 % 3 --> 1
7 % -3 --> 1
-7 % 3 --> -1
-7 % -3 --> -1
要的模OP是一个经典的欧几里得模,而不是%。
我以为每次都会有积极的结果。
要执行定义良好的欧几里得模,只要a/b有定义,a,b是任意符号,且结果永远不为负:
int modulo_Euclidean(int a, int b) {
int m = a % b;
if (m < 0) {
// m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
m = (b < 0) ? m - b : m + b;
}
return m;
}
modulo_Euclidean( 7, 3) --> 1
modulo_Euclidean( 7, -3) --> 1
modulo_Euclidean(-7, 3) --> 2
modulo_Euclidean(-7, -3) --> 2
我认为在抽象算术中定义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语言实现的不是余,而是余数。不管怎样,关键是返回负号是有意义的。
在数学中,这些惯例的起源,没有断言模算术应该产生一个正的结果。
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的因数)
要进一步阅读,请参阅数学中的等价类。
根据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是一个余数运算,而不是一个模运算。