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

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

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

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


当前回答

模量可以是负的吗?

%可以是负数,因为它是余数运算符,是除法后的余数,而不是欧几里得除法后的余数。由于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   

其他回答

其他答案已经在C99或更高版本中解释过,涉及负操作数的整数除法总是截断为零。

注意,在C89中,结果向上舍入还是向下舍入是由实现定义的。因为(a/b) * b + a%b在所有标准中都等于a,包含负操作数的%的结果也是在C89中实现定义的。

模运算的结果取决于分子的符号,因此y和z都是-2

这是参考资料

http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html

整数的除法 介绍整数除法的函数。 这些函数在GNU C库中是多余的,因为在GNU C中 '/'运算符总是四舍五入到零。但是在其他C中 实现中,'/'可以用不同的负参数四舍五入。 Div和ldiv很有用,因为它们指定了如何舍入 商:趋于零。余数的符号和 分子。

我认为在抽象算术中定义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语言实现的不是余,而是余数。不管怎样,关键是返回负号是有意义的。

模量可以是负的吗?

%可以是负数,因为它是余数运算符,是除法后的余数,而不是欧几里得除法后的余数。由于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   

模算子给出余数。 c中的模算子通常取分子的符号

X = 5%(-3)这里分子是正的,所以结果是2 Y =(-5) %(3)分子为负,结果为-2 Z =(-5) %(-3)这里分子是负的所以结果是-2

此外,模(余数)运算符只能用于整型,不能用于浮点数。