具有负值的模运算符

时间:2011-09-29 08:30:55

标签: c++

为什么要进行此类操作:

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

给出不同的结果?

-1
1

3 个答案:

答案 0 :(得分:176)

来自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)中

答案 1 :(得分:19)

符号在这种情况下(即当一个或两个操作数为负数时)是实现定义的。规范在§5.6/ 4(C ++ 03)中说明,

  

二元/运算符产生商,二元%运算符从第一个表达式除以第二个表达式得到余数。如果/或%的第二个操作数为零,则行为未定义;否则(a / b)* b + a%b等于a。如果两个操作数都是非负的,那么余数是非负的; 如果没有,余数的符号是​​实现定义的

就C ++ 03而言,这就是所有语言所必须说的。

答案 2 :(得分:16)

a % b

in c ++ default:

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

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

在python中:

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

在c ++到python中:

(b + (a%b)) % b