问题
Possible Duplicate:
C++ operator % guarantees
In c++ 98/03
5.6-4
The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
In c++ 11:
5.6 -4
The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded;81 if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.
As you can see the implementation-defined for the sign bit is missing, what happens to it ?
回答1:
The behaviour of %
was tightened in C++11, and is now fully specified (apart from division by 0
).
The combination of truncation towards zero and the identity (a/b)*b + a%b == a
implies that a%b
is always positive for positive a
and negative for negative a
.
The mathematical reason for this is as follows:
Let ÷
be mathematical division, and /
be C++ division.
For any a and b, we have a÷b = a/b + f
(where f is the fractional part), and from the standard, we also have (a/b)*b + a%b == a
.
a/b
is known to truncate towards 0
, so we know that the fractional part will always be positive if a÷b
is positive, and negative is a÷b
is negative:
sign(f) == sign(a)*sign(b)
a÷b = a/b + f
can be rearranged to give a/b = a÷b - f
. a
can be expanded as (a÷b)*b
:
(a/b)*b + a%b == a
=> (a÷b - f)*b+a%b == (a÷b)*b
.
Now the left hand side can also be expanded:
(a÷b)*b - f*b + a%b == (a÷b)*b
a%b == f*b
Recall from earlier that sign(f)==sign(a)*sign(b)
, so:
sign(a%b) == sign(f*b) == sign(a)*sign(b)*sign(b) == sign(a)
回答2:
The algorithm says (a/b)*b + a%b = a
, which is easier to read if you remember that it's truncate(a/b)*b + a%b = a
Using algebra, a%b = a - truncate(a/b)*b
. That is to say, f(a,b) = a - truncate(a/b)*b
. For what values is f(a,b) < 0
?
It doesn't matter if b
is negative or positive. It cancels itself out because it appears in the numerator and the denominator. Even if truncate(a/b) = 0
and b
is negative, well, it's going to be canceled out when it's a product of 0
.
Therefore, it is only the sign of a
that determines the sign of f(a,b)
, or a%b
.
来源:https://stackoverflow.com/questions/13100711/operator-modulo-change-in-c-11