可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In a c program i was trying the below operations(Just to check the behavior )
x = 5 % (-3);
y = (-5) % (3);
z = (-5) % (-3);
printf(\"%d ,%d ,%d\", x, y, z);
gave me output as (2, -2 , -2)
in gcc . I was expecting a positive result every time. Can a modulus be negative? Can anybody explain this behavior?
回答1:
C99 requires that when a/b
is representable:
(a/b) * b
+ a%b
shall equal a
This makes sense, logically. Right?
Let\'s see what this leads to:
Example A. 5/(-3)
is -1
=> (-1) * (-3)
+ 5%(-3)
= 5
This can only happen if 5%(-3)
is 2.
Example B. (-5)/3
is -1
=> (-1) * 3
+ (-5)%3
= -5
This can only happen if (-5)%3
is -2
回答2:
The %
operator in C is not the modulo operator but the remainder operator.
Modulo and remainder operators differ with respect to negative values.
With a remainder operator, the sign of the result is the same as the sign of the dividend while with a modulo operator the sign of the result is the same as the divisor.
C defines the %
operation for a % b
as:
a == (a / b * b) + a % b
with /
the integer division with truncation towards 0
. That\'s the truncation that is done towards 0
(and not towards negative inifinity) that defines the %
as a remainder operator rather than a modulo operator.
回答3:
Based on the C99 Specification: a = (a / b) * b + a % b
We can write a function to calculate (a % b) = a - (a / b) * b
!
int remainder(int a, int b)
{
return a - (a / b) * b;
}
For modulo operation, we can have the following function (assuming b>0)
int mod(int a, int b)
{
int r = a % b;
return r < 0 ? r + b : r;
}
My conclusion is (a % b) in C is a remainder operator and NOT modulo operator.
回答4:
I don\'t think there isn\'t any need to check if the number is negative.
A simple function to find the positive modulo would be this -
int modulo(int x,int N){
return (x % N + N) %N;
}
Assuming N is positive, this will work for both positive and negative values of x.
P.S. also as pointed out by @chux, If your x and N may reach something like INT_MAX-1 and INT_MAX respectively, just replace int
with long long int
.
And If they are crossing limits of long long as well (i.e. near LLONG_MAX), then you shall handle positive and negative cases separately as described in other answers here.
回答5:
The other answers have explained in C99 or later, division of integers involving negative operands always truncate towards zero.
Note that, in C89, whether the result round upward or downward is implementation-defined. Because (a/b) * b + a%b
equals a
in all standards, the result of %
involving negative operands is also implementation-defined in C89.
回答6:
The result of Modulo operation depends on the sign of numerator, and thus you\'re getting -2 for y and z
Here\'s the reference
http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html
Integer Division
This section describes functions for performing integer division.
These functions are redundant in the GNU C library, since in GNU C the
\'/\' operator always rounds towards zero. But in other C
implementations, \'/\' may round differently with negative arguments.
div and ldiv are useful because they specify how to round the
quotient: towards zero. The remainder has the same sign as the
numerator.
回答7:
In Mathematics, where these conventions stem from, there is no assertion that modulo arithmetic should yield a positive result.
Eg.
1 mod 5 = 1, but it can also equal -4. That is, 1/5 yields a remainder 1 from 0 or -4 from 5. (Both factors of 5)
Similarly,
-1 mod 5 = -1, but it can also equal 4. That is, -1/5 yields a remainder -1 from 0 or 4 from -5. (Both factors of 5)
For further reading look into equivalence classes in Mathematics.
回答8:
Can a modulus be negative?
%
is the remainder operator, the remainder after division, not after Euclidean_division. Since C99 the result may be 0, negative or positive.
// a % b
7 % 3 --> 1
7 % -3 --> 1
-7 % 3 --> -1
-7 % -3 --> -1
I was expecting a positive result every time.
To perform a Euclidean modulo that is well defined whenever a/b
is defined, a,b
are of any sign and the result is never negative:
int modulo_Euclidean(int a, int b) {
int m = a % b;
if (m < 0) {
// m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
m = (b < 0) ? m - b : m + b;
}
return m;
}
modulo_Euclidean( 7, 3) --> 1
modulo_Euclidean( 7, -3) --> 1
modulo_Euclidean(-7, 3) --> 2
modulo_Euclidean(-7, -3) --> 2
回答9:
Modulus operator gives the remainder.
Modulus operator in c usually takes the sign of the numerator
- x = 5 % (-3) - here numerator is positive hence it results in 2
- y = (-5) % (3) - here numerator is negative hence it results -2
- z = (-5) % (-3) - here numerator is negative hence it results -2
Also modulus(remainder) operator can only be used with integer type and cannot be used with floating point.
回答10:
According to C99 standard, section 6.5.5
Multiplicative operators, the following is required:
(a / b) * b + a % b = a
Conclusion
The sign of the result of a remainder operation, according
to C99, is the same as the dividend\'s one.
Let\'s see some examples (dividend / divisor
):
When only dividend is negative
(-3 / 2) * 2 + -3 % 2 = -3
(-3 / 2) * 2 = -2
(-3 % 2) must be -1
When only divisor is negative
(3 / -2) * -2 + 3 % -2 = 3
(3 / -2) * -2 = 2
(3 % -2) must be 1
When both divisor and dividend are negative
(-3 / -2) * -2 + -3 % -2 = -3
(-3 / -2) * -2 = -2
(-3 % -2) must be -1
6.5.5 Multiplicative operators
Syntax
- multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
Constraints
- Each of the operands shall have arithmetic type. The
operands of the % operator shall have integer type.
Semantics
The usual arithmetic conversions are performed on the
operands.
The result of the binary * operator is the product of
the operands.
The result of the / operator is the quotient from
the division of the first operand by the second; the
result of the % operator is the remainder. In both
operations, if the value of the second operand is zero,
the behavior is undefined.
When integers are divided, the result of the / operator
is the algebraic quotient with any fractional part
discarded [1]. If the quotient a/b
is representable,
the expression (a/b)*b + a%b
shall equal a
.
[1]: This is often called \"truncation toward zero\".
回答11:
The modulo operator is just like the mod operator when the number is positive, but different if the number is negative.
Many a times in the problems we are asked to give the answer modulo 10^9+7.
Let the answer(before using modulo) be denoted by \'a\'.
Simple Straightforward Rule-
if a is positive, then a modulo 10^9+7= a%(10^9+7)
if a is negative, then a modulo 10^9+7= (a%(10^9+7))+(10^9+7)
If, in such problems, we find that any step of the loop may calculate a value that is out of the integer range (if we are using integers), then we can use the modulo operator in that step itself. The final answer will be as if we have used the modulo operator only once.
This is because- (a*b)%c=((a%c)(b%c))%c Same goes for addition and subtraction.