【发布时间】:2013-05-16 10:43:38
【问题描述】:
请解释以下原因,因为数学上这两种情况的正确答案都是-2:
int a=7%-5; //Assigns 2 to a
int a=-7%5; //Assigns -2 to a
代码是 C 语言。
【问题讨论】:
请解释以下原因,因为数学上这两种情况的正确答案都是-2:
int a=7%-5; //Assigns 2 to a
int a=-7%5; //Assigns -2 to a
代码是 C 语言。
【问题讨论】:
7 / -5 = -1 余数为2,因为-1 * -5 + 2 = 5 + 2 = 7。
-7 / 5 = -1 余数为-2,因为-1 * 5 + (-2) = -5 - 2 = -7。
C++ 中的% 是余数运算符(对于正数,它用作数学模运算符)。
【讨论】:
因为在大多数 C 实现中,整数除法截断并且不会向负无穷大舍入。您的实现似乎也是其中之一。
a % b = a - (a / b) * b
所以
7 % (-5) = 7 - (7 / -5) * (-5)
这是
7 % (-5) = 7 - (-1) * (-5) = 7 - 5 = 2
【讨论】:
在 C 90 或 C++ 98 标准中没有指定负数的模数应该是什么符号。任何一个都可以接受。它在 C 99 和 C++ 2011 中被定义为与被除数具有相同的符号。
有关模数和余数之间差异的讨论,请参阅这篇文章:
还有这篇维基百科上的文章,它引用了标准状态。
【讨论】:
答案不是数学的,而是常规的。理论上,模运算符总是有两种可能的结果,负数和正数。
7 % 5
是 2 或 -3。
在数学中,大多数情况下使用积极的结果。在取决于编程语言的编程中。
原始 C 没有指定使用哪一个。使用正数,您总是得到正模数;对于负数,结果取决于所使用的编译器。
C-99 指定模数的结果应该与被除数具有相同的符号。这解释了你观察到的行为。
您可以在不同的编程语言here看到模运算符的结果。
【讨论】:
规则是r = a - (a/b) * b
所以
2 = 7 - (7/-5)*(-5) // note: 7/-5 is -1
【讨论】:
模运算负值在 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 中,问题在于算法是实现定义的, 所以你需要为负数滚动你自己的模运算 如果你希望你的程序是可移植的。
【讨论】: