问题
Please explain the reason behind the following, as mathematically the correct answer is -2
in both cases:
int a=7%-5; //Assigns 2 to a
int a=-7%5; //Assigns -2 to a
The code is in C.
回答1:
7 / -5 = -1
with remainder 2
, because -1 * -5 + 2 = 5 + 2 = 7
.
-7 / 5 = -1
with remainder -2
, because -1 * 5 + (-2) = -5 - 2 = -7
.
%
in C++ is a remainder operator (which for positive numbers works as a mathematical modulo operator).
回答2:
Because in most C implementations, integer division truncates and does not round towards negative infinity. Your implementation also appears to be one of these.
a % b = a - (a / b) * b
so
7 % (-5) = 7 - (7 / -5) * (-5)
which is
7 % (-5) = 7 - (-1) * (-5) = 7 - 5 = 2
回答3:
It's not specified in the C 90 or C++ 98 standard what sign the modulus of a number with a negative number should be. Either is acceptable. It is defined in C 99 and C++ 2011 however as having the same sign as the dividend.
For a discussion of the difference between a modulus and a remainder, see this article:
- http://blogs.msdn.com/b/ericlippert/archive/2011/12/05/what-s-the-difference-remainder-vs-modulus.aspx?Redirected=true
Also this article on Wikipedia, which references the standards status.
- https://en.wikipedia.org/wiki/Modulo_operation
回答4:
The answer is not mathematical, but conventional. Theoretically modulo operator always have two possible outcomes, negative and positive.
7 % 5
is either 2
or -3
.
In mathematics mostly positive outcome is used. In programming that depends on the programming language.
Original C does not specify which one to use. With positive numbers you always get positive modula; with negative numbers the result depends on the compiler used.
C-99 specifies that the result of modula should have the same sign with dividend. That explains the behaviour you observe.
You can see the outcome of modulo operator at different programming languages here.
回答5:
The rule is r = a - (a/b) * b
So
2 = 7 - (7/-5)*(-5) // note: 7/-5 is -1
回答6:
Modulo operation with negative values has no single definition in IT. There's three different algorithms:
- Truncated division
- Floored division
- Euclidean division
that provide equal results when the operands are positive, but different results when they are negative.
More information
Many implementations use truncated division where the quotient is defined by truncation q = trunc(a/n), in other words it is the first integer in the direction of 0 from the exact rational quotient, and the remainder by r=a − n q. Informally speaking the quotient is "rounded towards zero", and the remainder therefore has the same sign as the dividend.
Knuth described floored division where the quotient is defined by the floor function q=floor(a/n) and the remainder r is
r = a - nq = a - n \left\lfloor {a \over n} \right\rfloor.
Here the quotient is always rounded downwards (even if it is already negative) and the remainder has the same sign as the divisor.
Raymond T. Boute introduces the Euclidean definition, which is the one in which the remainder is always positive or 0, and is therefore consistent with the division algorithm (see Euclidean division). This definition is marked as "Always positive" in the table. Let q be the integer quotient of a and n, then:
In C, the catch is that the algorithm is implementation defined, so you need to roll your own modulo operation for negative numbers if you want your programs to be portable.
来源:https://stackoverflow.com/questions/16585325/why-7-5-gives-2-but-75-gives-2-shouldnt-it-be-2-in-both-cases