c99 standard says that result of modulo operation has same sign as first operand. So -9 % 7 = -2 and 9 % -7 = 2.
I read in one book that c89 standard depends on implementation. So -9 % 7 could yield -2 or 5??? How remainder of -9 / 7 could be 5?
Consider two numbers a and b.
The quotient q=a/b and remainder r=a%b satisfy the equation a == q*b + r.
An (hypothetical) implementation of C89 in which -9 % 7 produces 5 is an implementation in which -9 / 7 is computed as -2.
The mathematical (Euclidian) division constrains r to be positive and smaller than b. C99 constrains it to be of the same sign as a and strictly between -b and b.
It is all only a matter of convention.
% operator is defined as:
a == (a / b * b) + a % b
so
a % b = a - (a / b * b)
% as a remainder operator
If / rounds towards 0 (like C99):
-9 % 7 == -2
you have -9 / 7 == -1 so the % is -2 because
-9 % 7 == -9 - (-9 / 7 * 7) + 9 == -9 + 7 == -2
% as a modulo operator
If / rounds towards minus infinity:
-9 % 7 == 5
you have -9 / 7 == -2 so the % is 5
-9 % 7 == -9 - (-9 / 7 * 7) + 9 == -9 + 14 == 5
Related
base-2: why DECIMAL_DIG - DIG == 2 or 3?
Examples:
FLT_DECIMAL_DIG - FLT_DIG == 9 - 6 == 3
DBL_DECIMAL_DIG - DBL_DIG == 17 - 15 == 2
LDBL_DECIMAL_DIG - LDBL_DIG == 21 - 18 == 3
FLT16_DECIMAL_DIG - FLT16_DIG == 5 - 3 == 2
Extra: Is it guaranteed that on any given implementation using base-2 this difference will be 2 or 3?
Yes, for base-2 radix, xxx_DECIMAL_DIG - xxx_DIG will be 2 or 3.
Informal proof
For a floating point type:
b is the base or radix or exponent representation (an integer > 1)
p is the precision (the number of base-b digits in the significand) (I assume this is > 1 and rational)
The xxx_DECIMAL_DIG values are defined as:
⎰ p log10 b — if b is a power of 10
⎱ ⌈1 + p log10 b⌉ — otherwise
The xxx_DIG values are defined as:
⎰ p log10 b — if b is a power of 10
⎱ ⌊(p - 1) log10 b⌋ — otherwise
For b = 2, log10 b ≈ 0.301 and is irrational (proof).
∴ p log10 2 is irrational (since p is rational and > 1).
∴ ⌈p log10 2⌉ - ⌊p log10 2⌋ = 1.
∴ ⌈1 + p log10 2⌉ - ⌊p log10 2⌋ = 2. — ①
⌊p log10 2⌋ - ⌊(p - 1) log10 2⌋ ∈ {0, 1}. — ② (since 0 < log10 2 < 1)
∴ ⌈1 + p log10 2⌉ - ⌊(p - 1) log10 2⌋ ∈ {2, 3}. — (from ① and ②) ∎
Given definitions of xxx_DECIMAL_DIG and xxx_DIG we have
2 <= ceil(1+p*log10(2)) - floor((p-1)*log10(2)) <= 3
Simplifying:
2 <= ceil(1+p*log10(2)) - floor((p-1)*log10(2)) <= 3
2 <= 1 + ceil( p*log10(2)) - floor((p-1)*log10(2)) <= 3
let q = p – 1
2 <= 1 + ceil( (1 + q) *log10(2)) - floor((p-1)*log10(2)) <= 3
2 <= 1 + ceil(log10(2) + q*log10(2)) - floor( q *log10(2)) <= 3
let R = trunc(q*log10(2))
let r = trunc(q*log10(2)) – R, r is [0.0 …1.0)
log10(2) = 0.301…
2 <= (1 + R + ceil(0.301… + r)) – (R + floor(r)) <= 3
2 <= 1 + ceil(0.301… + r) – floor(r) <= 3
2 <= 1 + ceil(0.301… + r) – 0 <= 3
When r <= 1.0 - 0.301…
2 <= 1 + 1 <= 3
Otherwise r > 1.0 - 0.301…
2 <= 1 + 2 <= 3
Even though it is shown that the difference is 2 or 3, I suppose the next questions are why are
xxx_DECIMAL_DIG: ceil(1+p*log10(2))
and
xxx_DIG: floor((p-1)*log10(2))?
I'm looking for an overflow-safe method to perform round division of unsigned integers.
I have this:
uint roundDiv(uint n, uint d)
{
return (n + d / 2) / d;
}
But unfortunately, the expression n + d / 2 may overflow.
I think that I will have to check whether or not n % d is smaller than d / 2.
But d / 2 itself may truncate (when d is odd).
So I figured I should check whether or not n % d * 2 is smaller than d.
Or even without a logical condition, rely on the fact that n % d * 2 / d is either 0 or 1:
uint roundDiv(uint n, uint d)
{
return n / d + n % d * 2 / d;
}
This works well, however once again, n % d * 2 may overflow.
Is there any custom way to achieve round integer division which is overflow-safe?
Update
I have come up with this:
uint roundDiv(uint n, uint d)
{
if (n % d < (d + d % 2) / 2)
return n / d;
return n / d + 1;
}
Still, the expression d + d % 2 may overflow.
return n/d + (d-d/2 <= n%d);
The way to avoid overflow at any stage is, as OP stated, to compare the remainder with half the divisor, but the result isn't quite as obvious as it first seems. Here are some examples, with the assumption that 0.5 would round up. First with an odd divisor:
Numerator Divisor Required Quotient Remainder Half divisor Quot < Req?
3 3 1 1 0 1 no
4 3 1 1 1 1 no
5 3 2 1 2 1 yes
6 3 2 2 0 1 no
Above, the only increment needed is when d / 2 < remainder. Now with an even divisor:
Numerator Divisor Required Quotient Remainder Half divisor Quot < Req?
4 4 1 1 0 2 no
5 4 1 1 1 2 no
6 4 2 1 2 2 yes
7 4 2 1 3 2 yes
8 4 2 2 0 2 no
But here, the increment is needed when d / 2 <= remainder.
Summary:
You need a different condition depending on odd or even divisor.
I calc -15 mod 18 and here are results:
C: -15 % 18 = -15 (http://codepad.org/DhzkZYHk)
Google: -15 mod 18 = 3 (Type -15 mod 18 into google's search box)
and results of -9 mod 5:
C: -9 % 5 = -4
Google: -9 mod 5 =1
Why these are differents? And how google calculate their mod?
Google's calculator does -15 mod 18 as
-15 = 18*(-1) + 3
giving a remainder of 3,
whereas C evaluates it as
-15 = 18*(0) - 15
and hence the expression becomes -15.
In general,
a = (a/b)*b + a%b
holds.
Because the % operator in Google is a modulus operator and the % operator in C is a remainder operator.
Modulus and remainder operators differ with respect to negative values. With the modulus operator the sign of the result is the sign of the divisor and with the remainder operator the sign of the result is the sign of the dividend.
if anyone could answer me why this works, it would be greatly appreciated. The exercise (chapter 4, ex 7 and 8) says that if you have the expression:
9 - ((total - 1) % 10)
then, you could be tempted to simplify it like this:
10 - (total % 10)
But this would not work. Instead he offers the alternative:
(10 - (total % 10)) % 10
Now, I understand how he got to the first simplification, but not why it's wrong, or why does the second one works.
Thanks in advance
x %m has a range of (-m, m) in most C implementations. Mathematically it is generally defined from (0, m). Hence by adding m the modulo again will convert the C to the mathematical one.
Consider the outputs for total = 10 to see that the second expression is not equivalent.
Note also that the third expression is not equivalent to the first expression unless total > 0 (because the behaviour of % is implementation-defined in pre-C99 C, and defined but not what you want in C99).
Assuming that total > 0, the first and third expressions are equivalent due to the following mathematical identity:
(a % b) == (((a + c) % b) - c) % b
To understand why, imagine doing the operations on a clock-face.
This is because modulo in C allows for negative numbers.
so -5 % 10 is -5 instead of 5.
In the first case, the 9 - ((total - 1) % 10) is always positive.
In the second case it can be negative if -10 < total < 0. In the 3rd case it is again wrapped around for negatives back into the positive range.
It is a common thing for modulo because generally you want it for positives only(not sure why they implemented it for negatives).
To show why 9-((total)%10) is wrong, use a contradiction.
Let total = 10.
Then 9-((10-1)%10) ==> 9-(9%10) ==> 9-9 = 0.
But, 10-(10%10) ==> 10 -0 = 10.
Thus, 10-((total)%10) is not equivalent to 9-((total-1)%10)
The alternative is not a simplification and neither expression is equvalent to the first so the premise is flawed from the start:
The following:
int total ;
for( total = -10; total <= 10; total++ )
{
printf( "%d:\t%d\t%d\t%d\n", total,
9 - ((total - 1) % 10),
10 - (total % 10),
(10 - (total % 10)) % 10 ) ;
}
Produces:
-10: 10 10 0
-9: 9 19 9
-8: 18 18 8
-7: 17 17 7
-6: 16 16 6
-5: 15 15 5
-4: 14 14 4
-3: 13 13 3
-2: 12 12 2
-1: 11 11 1
0: 10 10 0
1: 9 9 9
2: 8 8 8
3: 7 7 7
4: 6 6 6
5: 5 5 5
6: 4 4 4
7: 3 3 3
8: 2 2 2
9: 1 1 1
10: 0 10 0
The last is only equvalent for integers greater than zero.
7 % 3 = 1 (remainder 1)
how does
3 % 7 (remainder ?)
work?
remainder of 3/7 is 3..since it went 0 times with 3 remainder so 3%7 = 3
7 goes into 3? zero times with 3 left over.
quotient is zero. Remainder (modulus) is 3.
Conceptually, I think of it this way. By definition, your dividend must be equal to (quotient * divisor) + modulus
Or, solving for modulus: modulus = dividend - (quotient * divisor)
Whenever the dividend is less than the divisor, the quotient is always zero which results in the modulus simply being equal to the dividend.
To illustrate with OP's values:
modulus of 3 and 7 = 3 - (0 * 7) = 3
To illustrate with other values:
1 % 3:
1 - (0 * 3) = 1
2 % 3:
2 - (0 * 3) = 2
The same way. The quotient is 0 (3 / 7 with fractional part discarded). The remainder then satisfies:
(a / b) * b + (a % b) = a
(3 / 7) * 7 + (3 % 7) = 3
0 * 7 + (3 % 7) = 3
(3 % 7) = 3
This is defined in C99 §6.5.5, Multiplicative operators.
7 divided by 3 is 2 with a remainder of 1
3 divided by 7 is 0 with a remainder of 3
As long as they're both positive, the remainder will be equal to the dividend. If one or both is negative, then you get reminded that % is really the remainder operator, not the modulus operator. A modulus will always be positive, but a remainder can be negative.
(7 * 0) + 3 = 3; therefore, the remainder is 3.
a % q = r means there is a x so that q * x + r = a.
So, 7 % 3 = 1 because 3 * 2 + 1 = 7,
and 3 % 7 = 3 because 7 * 0 + 3 = 3
It seems you forgot to mention the surprising case, if the divident is smaller and negative:
-3 % 7
result: 4
For my brain to understand this kind of question, I'm always converting it to a real world object, for example if I convert your question 3 % 7. I'm going to represent the "3" as a 3-inch wide metal hole, then the "7" as a 7 inch metal screw. Can you insert the 7 inch metal screw to a 3 inch wide metal hole? Of course not, therefore the answer should be the 3-inch metal hole, it doesn't matter even let say you have a 1000 or a million inch wide screw, it is still 3, because how many times can you insert the 1000 or a million inch wide screw to a 3 inch wide metal hole? Zero times, right?
The most simple and effective catch to remember would be:
Whenever dividend is less than the divisor, modulus is just that dividend.
Let's formulate this:
if x < y, then x % y = x