0

请解释以下原因,因为从数学上讲-2,两种情况下的正确答案都是:

int a=7%-5; //Assigns 2 to a
int a=-7%5;  //Assigns -2 to a

代码在 C 中。

4

6 回答 6

12

7 / -5 = -1有余数2,因为-1 * -5 + 2 = 5 + 2 = 7.

-7 / 5 = -1有余数-2,因为-1 * 5 + (-2) = -5 - 2 = -7.

%在 C++ 中是一个余数运算符(对于正数,它用作数学模运算符)。

于 2013-05-16T10:48:27.393 回答
3

因为在大多数 C 实现中,整数除法会截断并且不会向负无穷大舍入。您的实现似乎也是其中之一。

a % b = a - (a / b) * b

所以

7 % (-5) = 7 - (7 / -5) * (-5)

这是

7 % (-5) = 7 - (-1) * (-5) = 7 - 5 = 2
于 2013-05-16T10:50:31.707 回答
0

在 C 90 或 C++ 98 标准中没有指定负数的模数应该是什么符号。任何一个都可以接受。它在 C 99 和 C++ 2011 中被定义为具有与被除数相同的符号。

有关模数和余数之间差异的讨论,请参阅这篇文章:

还有这篇维基百科上的文章,它引用了标准状态。

于 2013-05-16T10:51:38.243 回答
0

答案不是数学的,而是传统的。理论上,模运算符总是有两种可能的结果,负数和正数。

7 % 5

要么2要么-3

在数学中,通常使用积极的结果。在取决于编程语言的编程中。

原始 C 没有指定使用哪一个。使用正数,您总是得到正模数;对于负数,结果取决于所使用的编译器。

C-99 指定模数的结果应该与被除数具有相同的符号。这解释了你观察到的行为。

您可以在此处查看不同编程语言的模运算符的结果。

于 2013-05-16T10:52:15.163 回答
0

规则是r = a - (a/b) * b

所以

2 = 7 - (7/-5)*(-5) // note: 7/-5 is -1

于 2013-05-16T10:52:20.143 回答
0

负值的模运算在 IT 中没有单一的定义。三种不同的算法:

  • 截断除法
  • 地板分区
  • 欧几里得除法

当操作数为正时提供相同的结果,但在操作数为负时提供不同的结果。

更多信息

许多实现使用截断除法,其中商由截断 q = trunc(a/n) 定义,换句话说,它是从精确有理商到 0 方向的第一个整数,余数为 r=a - n q . 非正式地讲,商“向零舍入”,因此余数与被除数具有相同的符号。

Knuth 描述了下限除法,其中商由下限函数 q=floor(a/n) 定义,余数 r 为

r = a - nq = a - n \left\lfloor {a \over n} \right\rfloor.

这里商总是向下舍入(即使它已经是负数),余数与除数的符号相同。

Raymond T. Boute 引入了欧几里得定义,即余数始终为正或 0 的定义,因此与除法算法一致(参见欧几里得除法)。这个定义在表中被标记为“总是积极的”。设 q 为 a 和 n 的整数商,则:

在 C 中,问题是算法是实现定义的,因此如果您希望程序可移植,则需要为负数滚动自己的模运算。

于 2013-05-16T10:52:23.010 回答