Gob*_*0st 11 c++ modulo language-lawyer c++11 c++03
可能重复:
C++运算符%保证
在c ++ 98/03中
5.6-4
二元/运算符产生商,二元%运算符从第一个表达式除以第二个表达式得到余数.如果/或%的第二个操作数为零,则行为未定义; 否则(a/b)*b + a%b等于a.如果两个操作数都是非负的,那么余数是非负的; 如果没有,余数的符号是实现定义的.
在c ++ 11中:
5.6 -4
二元/运算符产生商,二元%运算符从第一个表达式除以第二个表达式得到余数.如果/或%的第二个操作数为零,则行为未定义.对于积分操作数,/运算符产生代数商,丢弃任何小数部分;如果商a/b在结果类型中可表示,则为(a/b)*b + a%b等于a.
正如您所看到的那样,为符号位定义的实现缺失了,它会发生什么?
Man*_*rse 19
%在C++ 11中,行为被收紧了,现在已经完全指定(除了除法0).
截断朝向零和身份的组合(a/b)*b + a%b == a意味着a%b对于正面a和负面总是正面的a.
数学原因如下:
让我们÷进行数学划分,/成为C++师.
对于任何a和b,我们有a÷b = a/b + f(其中f是小数部分),而且从标准中我们也有(a/b)*b + a%b == a.
a/b已知截断朝向0,所以我们知道如果a÷b是正数,则小数部分将始终为正,而负数a÷b则为负数:
sign(f) == sign(a)*sign(b)
a÷b = a/b + f可以重新安排给予a/b = a÷b - f.a可以扩展为(a÷b)*b:
(a/b)*b + a%b == a=> (a÷b - f)*b+a%b == (a÷b)*b.
现在左侧也可以扩展:
(a÷b)*b - f*b + a%b == (a÷b)*b
a%b == f*b
回想一下早些时候sign(f)==sign(a)*sign(b),所以:
sign(a%b) == sign(f*b) == sign(a)*sign(b)*sign(b) == sign(a)