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);
It 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?
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
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 (numerator) while with a modulo operator the sign of the result is the same as the divisor (denominator).
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.
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 that a % b in C is a remainder operation and NOT a modulo operation.
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 -
Edit: Assuming N > 0 and N + N - 1 <= INT_MAX
int modulo(int x,int N){
return (x % N + N) %N;
}
This will work for both positive and negative values of x.
Original 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.
Can a modulus be negative?
% can be negative as it 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
The modulo OP wanted is a classic Euclidean modulo, not %.
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
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.
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".
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.
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.
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.
I believe it's more useful to think of mod as it's defined in abstract arithmetic; not as an operation, but as a whole different class of arithmetic, with different elements, and different operators. That means addition in mod 3 is not the same as the "normal" addition; that is; integer addition.
So when you do:
5 % -3
You are trying to map the integer 5 to an element in the set of mod -3. These are the elements of mod -3:
{ 0, -2, -1 }
So:
0 => 0, 1 => -2, 2 => -1, 3 => 0, 4 => -2, 5 => -1
Say you have to stay up for some reason 30 hours, how many hours will you have left of that day? 30 mod -24.
But what C implements is not mod, it's a remainder. Anyway, the point is that it does make sense to return negatives.
It seems the problem is that / is not floor operation.
int mod(int m, float n)
{
return m - floor(m/n)*n;
}
Related
Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).
I have seen many answers for questions concerning modulo of negative numbers. Every answer placed the standard
(a/b)*b + a%b is equal to a
explanation. I can calculate any modulo with this method, and I understand it's necessary employ a modulo function that adds b to the value of a%b if it is negative for the modulo to make sense.
I am trying to make sense of this in laymen's terms. Just what is the modulo of a negative number? I read somewhere that you can calculate the proper modulo of negative numbers by hand some laymen's method of just adding numbers together. This would be helpful, because the a/b *b + a%b method is a little tedious.
To clarify, the modulo of a positive number can be interpreted in laymen's terms as the remainder when you divide the numbers. Obviously this isn't true in the case of negative numbers, so how do you properly "make sense" of the result?
This used to be implementation-defined in older revisions of C++, but now it's all fully specified:
Division truncates, i.e. a / b is the mathematical value with the fractional part discarded. For example, 9 / -5 is the truncation of −1.8, so it's -1.
The remainder operation a % b is defined by the identity you presented. So let's compute: (a / b) * b is -1 * -5 is 5, so 9 % -5 is 4.
By contrast,-9 % 5 is -4. So even though a / -b is the same as -a / b, a % -b is in general different from -a % b. (Similarly, the mathematical notion of modular equivalence, where two integers are congruent modulo n if they differ by an integral multiple of n, is invariant under replacing n with -n.)
TL;DR: There is a difference between modulo operator which is used in math and C++ % operator.
For example, let f(x) = x % 4. Then:
x : -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9
f(x) in math : 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 0 1
f(x) in C : -1 -0 -3 -2 -1 0 -3 -2 -1 0 1 2 3 0 1 2 3 0 1
^~~~~~~~~~~~~~~~~~~~~~~~^
This part is different
You don't need any special tricks to compute C++-style % of a negative number.
Just use a%b == a - (a/b)*b, which is derived from (a/b)*b + a%b == a.
Long answer:
Cppreference says following:
The binary operator % yields the remainder of the integer division of the first operand by the second (after usual arithmetic conversions; note that the operand types must be integral types). If the quotient a/b is representable in the result type, (a/b)*b + a%b == a. If the second operand is zero, the behavior is undefined. If the quotient a/b is not representable in the result type, the behavior of both a/b and a%b is undefined (that means INT_MIN%-1 is undefined on 2's complement systems)
Note: Until C++11, if one or both operands to binary operator % were negative, the sign of the remainder was implementation-defined, as it depends on the rounding direction of integer division. The function std::div provided well-defined behavior in that case.
The important parts are:
(a/b)*b + a%b == a.
"Until C++11, if one or both operands to binary operator % were negative, the sign of the remainder was implementation-defined."
This implies that since C++11 the operator is well-defined for negative operands too.
There is no mention of any special handling of negative operands, thus we can say that above identity words for them too.
From (a/b)*b + a%b == a we can easily derive a formula for a%b:
a%b == a - (a/b)*b
If you think about it, this formula ignores the sign of b, works as if the modulo was computed with the absolute value of a, with the sign of a appended to the result.
If you want to compute the "classical" modulo, you may use something like following function:
template <typename T, typename TT> constexpr T true_mod(T a, TT b)
{
static_assert(std::is_integral<T>::value &&
std::is_integral<TT>::value, "Argument types must be integral.");
if (a >= 0)
return a % b;
else
return (b >= 0 ? b : -b) - 1 + (a + 1) % b;
}
(a/b)*b + a%b is equal to a
Even if this statement is true, the result can change from a language to an other.
This difference also depends on the result of the division.
for example, in python, I have:
>>> # in python, use "//" for the floor division
>>> 3 // 4 # 0.75 is rounded to 0 : OK
0
>>> 3 % 4 # still as expected
3
>>> 0 * 4 + 3 # standard valided
3
>>> (-3) // 4 # -0.75 is rounded to -1, not 0 (the floor)
-1
>>> (-3) % 4 # the result is consistant; a modulo garanteed to be between 0 and b is very usefull
1
>>> (-1) * 4 + 1 # standard valided
-3
>>> 3 // (-4) # -0.75 is rounded to -1, not 0 (the floor)
-1
>>> 3 % (-4) # still a number between 0 and b
-1
>>> (-1) * (-4) + (-1) # standard valided
3
SUMMARY:
MODULO TEST: language=python
a=3 b=4 a/b=0 a%b=3 standard:true
a=-3 b=4 a/b=-1 a%b=1 standard:true
a=3 b=-4 a/b=-1 a%b=-1 standard:true
a=-3 b=-4 a/b=0 a%b=-3 standard:true
If my memory is good, the modulo doesn't work like that in C, even if the standard is valided. It can be very disturbing.
I've juste written a little programm to test the results in C:
#include <stdio.h>
void test(int a, int b) {
int q = a/b;
int r = a%b;
int ok = q*b+r == a;
printf("a=%-2d b=%-2d a/b=%-2d a%%b=%-2d standard:%s\n", a, b, q, r, ok?"true":"false");
}
int main(int argc, char const *argv[]) {
printf("MODULO TEST: language=c\n");
test( 3, 4);
test(-3, 4);
test( 3,-4);
test(-3,-4);
return 0;
}
which gives:
MODULO TEST: language=c
a=3 b=4 a/b=0 a%b=3 standard:true
a=-3 b=4 a/b=0 a%b=-3 standard:true
a=3 b=-4 a/b=0 a%b=3 standard:true
a=-3 b=-4 a/b=0 a%b=-3 standard:true
So yes, the standard is not enough to fix a unique method for the modulo of two (negative) numbers.
You could use this code when the left number has an unknown sign :
int mod = a % b;
if (mod*b < 0) mod += b;
This code will give you a number between 0 and b all the time, like in python (0 <= mod < b, or b < mod <= 0 if b is negative).
The * b is useless if b is strictly positive (in most of the cases).
EDIT
Using a XOR is better than a multiplication, as it prevents overflow.
int mod = a % b;
if ((mod < 0) ^ (b < 0)) mod += b;
And when b is strictly positive:
int mod = a % b;
if (mod < 0) mod += b;
EDIT 2 (2018-10-09)
Better use this, to use python-style division (modulo between 0 included and b excluded) in C:
int q = a / b;
int r = a % b;
if ((b<0) ? (r<0) : (r>0)) {
q -= 1;
r += b;
}
It prevents "extremes" cases like b is negative and divides a (like 6 % (-3)). The result must be 0.
Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).
Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).
$5.6/4 in C++03 states- "If both
operands are nonnegative then the
remainder is nonnegative;if not, the
sign of the remainder is
implementation-defined74).
where Note 74 is
According to work underway toward the
revision of ISO C, the preferred
algorithm for integer division
follows the rules defined inthe ISO
Fortran standard, ISO/IEC 1539:1991,
in which the quotient is always
rounded toward zero.
C++0x states -
$5.6/4- "For integral operands the / operator yields the algebraic quotient with any fractional part discarded;79 if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a.
Note 79 says
This is often called truncation towards zero.
So I have two questions:
Can someone explain this concept of 'truncation towards zero'?
Is modulus with negative operands a defined behavior in C++0x?
Truncation towards zero means converting a real number to an integer by selecting the next integer nearest zero. Equivalently, you write the number down, and ignore everything after the decimal point, whether the number is positive or negative.
Consider 11/4 = 2.75 -- if you truncate this towards zero, you get 2.
consider -11/4 or 11/-4 = -2.75 -- if you truncate this towards zero, you get -2.
It's important for some maths operations that (a/b)*b + a%b == a. If we must make this equation hold, and we also accept that integer division truncates towards zero, then we can deduce the operation of the % operator as follows:
a == 11, b == 4:
a/b == 2, 2*4 + a%b == 11, therefore a%b == 3.
a == -11, b == 4:
a/b == -2, -2 * 4 + a%b == -11, therefore a%b == -3.
a == 11, b == -4:
a/b == -2, -2 * -4 + a%b == 11, therefore a%b == 3.
a == -11, b == -4:
a/b == 2, 2 * -4 + a%b == -11, therefore a%b == -3.
It might be confusing at first, but C++0x is defining the behaviour of the a%b operator using the equation (a/b)*b + a%b == a. This equation holds even for negative numbers, so a%b is defined for negative numbers.
a) Consider (±5)/(±3) -> ±1. On the number line:
(-5)/3 5/3
5/(-3) (-5)/(-3)
= =
-1.66 --> -1 1 <-- 1.66
v v v v
- + - - - + - - - + - - - + - - - + -
| | | | |
-2 -1 0 1 2
the rounding is thus towards zero.
b) Yes. Since a/b is now defined for all a and b (except b == 0), and (a/b)*b + a%b == a, there is only 1 unique solution for a%b, so the % operator is also well-defiend for all a and b (except b == 0).
a) "Truncation towards zero" simply means that any decimal part is lopped off. The truncated number is always at least as close to 0 as, and usually closer than, the original number.
This is most noticeable in negative numbers, but the goal is to make it less tricky to use / and % with negative numbers (since currently, any implementation can handle it however they choose). -7/4 can be thought of two ways: -2 with a remainder of 1, or -1 with a remainder of -3. And there are compilers and processors that handle it both ways. Since -7/4 is actually -1.75, "truncation toward zero" would give you -1, so the latter way is what'll be standard.
b)
That's what it looks like. It's always been semi-defined ("implementation-defined"), but this looks like an attempt to define what should have been standard from the beginning.