在C ++ 11运营商模的变化? [重复](operator modulo change in

2019-07-02 18:42发布

可能重复:
C ++操作符%的保证

在C ++ 98/03

5.6-4

二进制/操作员产生的商,和二进制%操作者产生了由第二所述第一表达的除法的余数。 如果/或%所述第二操作数是零的行为是未定义; 否则(A / B)* B + A%b等于一个。 如果两个操作数都是非负,则剩余部分非负; 如果没有,其余的标志是实现定义的

在C + + 11:

5.6 -4

二进制/操作员产生的商,和二进制%操作者产生了由第二所述第一表达的除法的余数。 如果/或%所述第二操作数是零的行为是未定义。 对于整型操作数/运算产生具有丢弃任何小数部分代数商; 81如果商A / B为在结果,(A / B)* B + A%b等于一个的类型表示的。

正如你所看到的实现定义为符号位丢失,会发生什么呢?

Answer 1:

的行为%的收紧在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 - fa可以被扩展为(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)



Answer 2:

该算法说(a/b)*b + a%b = a ,这是比较容易,如果你还记得它的读取truncate(a/b)*b + a%b = a使用代数, a%b = a - truncate(a/b)*b 。 也就是说, f(a,b) = a - truncate(a/b)*b 。 对于哪些值是f(a,b) < 0

如果不要紧, b为阴性或阳性。 因为它出现在分子和分母自身消去。 即使truncate(a/b) = 0b是负的,那么,它会被抵消时,它的的产物0

因此,只有迹象a确定的符号f(a,b)a%b



文章来源: operator modulo change in c++ 11? [duplicate]