负值模运算符

为什么要进行这样的操作:

std::cout << (-7 % 3) << std::endl;
std::cout << (7 % -3) << std::endl;

给出不同的结果?

-1
1
204646 次浏览

在这种情况下(即一个或两个操作数都为负) ,签字是实现定义的。规范说在5.6/4(C + + 03),

二进制/运算符生成商,二进制% 运算符生成第一个表达式除以第二个表达式的余数。如果/或% 的第二个操作数为零,则行为是未定义的; 否则(a/b) * b + a% b 等于。如果两个操作数都是非负的,那么余数就是非负的;。

对于 C + + 03来说,这就是语言要说的全部内容。

由 ISO14882:2011(e)5.6-4:

二进制/运算符生成商和二进制% 运算符 将第一个表达式除以 如果/或% 的第二个操作数为零,则行为为 未定义。对于整数操作数,/运算符产生丢弃任意小数部分的代数商; 如果商 a/b 为 (a/b) * b + a% b 等于 a。

剩下的就是基础数学了:

(-7/3) => -2
-2 * 3 => -6
so a%b => -1


(7/-3) => -2
-2 * -3 => 6
so a%b => 1

请注意

如果两个操作数都是非负的,那么余数就是非负的; 如果 不,余数的符号是实现定义的。

ISO14882:2003(e)标准已不再适用于 ISO14882:2011(e)标准

a % b

C + + 默认值:

(-7/3) => -2
-2 * 3 => -6
so a%b => -1


(7/-3) => -2
-2 * -3 => 6
so a%b => 1

在巨蟒中:

-7 % 3 => 2
7 % -3 => -2

从 c + + 到 python:

(b + (a%b)) % b