This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to code a modulo (%) operator in C/C++/Obj-C that handles negative numbers
From what I understand (see Modulo operator with negative values and Modulo operation) C & C++ have a "remainder" operator a % b but no operator that actually does modular arithmetic when the LHS is negative.
Several languages do have such a function. Is it possible to build an efficient function in C/C++ (or is there no efficient way to do it on i686/x64 CPUs)?
Currently I use (n * b + a) % b where n is picked such that I'm fairly sure the entire LHS is non-negative, but inevitably code gets changed and bugs sometimes occur.
Note: in case it's not clear, by modular arithmetic I mean an operator such that a + b % b = a % b for all integers a and all positive integers b.
There is no simple way to do it, however it is more efficient if you create a two-line solution, and spare a multiplication plus determining n.
inline int modulo(int a, int b) {
const int result = a % b;
return result >= 0 ? result : result + b;
}
Also, if you need to work correctly for negative b numbers as well, add to the beginning:
if(b < 0) return modulo(-a, -b);
I would suggest a function like the one above, but using inline int modulo(int a, int b) {} (just as if the operator existed in C++). Personnally I don't use negative numbers often, and still think you should keep % whenever your code doesn't use negative numbers.
Related
If I have 2 int or long long variables, call them a and b, and I want to compute the sum (a + b) mod p, where p is a large prime integer, how can I utilize the modulo operator in C++ to achieve the desired result?
I have tried (a + b) % p, but this gives overflow sometimes, since a + b will overflow before the mod is applied.
Other similar approaches I have tried seem to avoid overflow, but give an incorrect result.
How can I use the modulo operator in this case to correctly compute the desired sum, while avoiding overflow?
a %= p
b %= p
c = p-a
if(b==c)
sum = 0
if (b<c)
sum = a+b
if (b>c)
sum = b-c
EDIT: The trick is to avoid any calculation that might cause overflow, without knowing where the limit is. All we know is that the given a, b and p are below the limit -- maybe just below the limit.
After the first two steps (a%=p;b%=p;) we know a<p and b<p. We still daren't add a+b, because that sum might exceed p and break the limit*. But we can see how much room we have left with c = p-a, which is safe because we know that c<=p and c>0. (The stated types are unsigned, but we may as well avoid negative numbers, if only because their limits are sometimes off by one from the negatives of the positive limits, in ways I can never remember.)
If b=c, then b=p-a, so a+b=p, so the sum (mod p) is zero.
If b<c, then a+b<p, so we can safely compute a+b (and need not apply the modulo).
if b>c, then it is not safe to compute a+b, but we know that the number we're looking for is a+b-p, which we can rewrite as b-(p-a), and we already have b and p-a, so we can safely perform that subtraction.
(*) That's right, I said "daren't". It's a perfectly good word.
This question already has answers here:
Operator precedence (bitwise '&' lower than '==')
(3 answers)
Closed 8 years ago.
I was trying to solve a Counter Game problem:
"Louise and Richard play a game. They have a counter set to N. Louise gets the first turn and the turns alternate thereafter. In the game, they perform the following operations.
If N is not a power of 2, they reduce the counter by the largest power of 2 less than N.
If N is a power of 2, they reduce the counter by half of N.
The resultant value is the new N which is again used for subsequent operations.
The game ends when the counter reduces to 1, i.e., N == 1, and the last person to make a valid move wins.
Given N, your task is to find the winner of the game."
To solve the question, I implemented bit manipulation, and got accepted:
#include <iostream>
#include <cstdio>
int main() {
long long unsigned int n, tmp;
int cnt, t;
scanf("%d", &t);
while(t--) {
scanf("%llu", &n), tmp=n;
cnt=0;
while(tmp) tmp&=tmp-1, cnt++;
cnt--;
while((n&1)==0) n>>=1, cnt++;
if(cnt%2==0) printf("Richard\n");
else printf("Louise\n");
}
return 0;
}
However, during the coding i coded while(n&1==false) instead of while((n&1)==false), thus could not get desired result. Coding while(!(n&1)) gave expected result, but that(!a instead of a==false) was bad practice due to some sources(I forgot them) I have read online. And I know the difference between while(!n&1) and while(!(n&1)), but I did not know while(n&1==false) and while((n&1)==false). Learnt the latter was and is dissimilar, and may I ask the distinction, please?
This is considered by many a design mistake of C.
While it's natural that a logical-and operation should have lower precedence than equality comparison the same is much more questionable for bitwise-and because bitwise operations are naturally closer to math operations.
The same design error has been inherited by C++ for backward compatibility.
A good rule is always parenthesize bitwise operations to avoid surprises.
As you can see here, the precedence of == is above the precedence of &.
Therefore n&1==false is interpreted as n&(1==false) not (n&1)==false, so you need the parentheses.
== has higher priority in C++ than & (source).
Thus while(n&1==false) is treated as while (n & (1 == false)) which actually is while (n & 0).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Best way to detect integer overflow in C/C++
I am writing a function in C but the question is generic. The function takes three integers and returns some information about these three integers.
Problem I suspect here is the integers can be at their max and this can cause overflow.
For example: if I pass a as maximum value possible and b can be anything 1 - max, then in this case, will the expression (a+b)>c in if condition cause overflow? If so, how do I handle it?
My solution was to keep a long integer as temporary variable to keep value of a+b and use it in the expression but it sounds dirty way.
Refer to this snippet:
int
triangle_type(int a, int b, int c) {
if (!((a+b)>c)&&((b+c) > a)&&((a+c>b))) {
return -1;
}
}
On current processors, there is no real signaling overflow on integers. So on a 32 bits processors, integer arithmetic is done modulus 2^32 at the bit level. When you add up two int-s and some "overflow" happens, an overflow (or carry) bit is set in some status register (and the arithmetic operation is done modulus 2^32). If (as it is usually the case) no machine instruction tests that overflow status bit, nothing happens.
So the control flow won't change because of an overflow (it usually will change on division by zero, e.g. with a SIGEMT signal).
If you want to portably catch in C the overflow case, you could test e.g. that the sum of two positive int-s stays positive. (if it is negative an overflow did happen).
You could also be interested in bignums, e.g. use the gmp library. You could also use <stdint.h> and use carefully int32_t and int64_t with explicit casts. At last, you could (as most coders do) choose to ignore that issue.
NB: As Jonathan noticed, you may fall in the undefined behavior or the unspecified behavior case. If you really care, use bignums. However, you may choose to not care at all.
You could do something like this
// returns true if a+b > c
inline int safe_sum_greater (int a, int b, int c) {
int a1 = a / 4; int a2 = a % 4;
int b1 = b / 4; int b2 = b % 4;
int c1 = c / 4; int c2 = c % 4;
int s2 = a2 + b2;
int s1 = a1 + b1 + s2 / 4;
s2 = s2 % 4;
return (s1 > c1) || ( (s1 == c1) && (s2 > c2) );
}
Performance won't be bad, since only bit-wise operations will be used.
I have not thought about this extensively for negative numbers, so use with care.
I'm trying to avoid long longs and integer overflow in some calculations, so I came up with the function below to calculate (a * b) / c (order is important due to truncating integer division).
unsigned muldiv(unsigned a, unsigned b, unsigned c)
{
return a * (b / c) + (a * (b % c)) / c;
}
Are there any edge cases for which this won't work as expected?
EDITED: This is correct for a superset of values for which the original obvious logic was correct. It still buys you nothing if c > b and possibly in other conditions. Perhaps you know something about your values of c but this may not help as much as you expect. Some combinations of a, b, c will still overflow.
EDIT: Assuming you're avoiding long long for strict C++98 portability reasons, you can get about 52 bits of precision by promoting your unsigned to doubles that happen to have integral values to do the math. Using double math may in fact be faster than doing three integral divisions.
This fails on quite a few cases. The most obvious is when a is large, so a * (b % c) overflows. You might try swapping a and b in that case, but that still fails if a, b, and c are all large. Consider a = b = 2^25-1 and c = 2^24 with a 32 bit unsigned. The correct result is 2^26-4, but both a * (b % c) and b * (a % c) will overflow. Even (a % c) * (b % c) would overflow.
By far the easisest way to solve this in general is to have a widening multiply, so you can get the intermediate product in higher precision. If you don't have that, you need to synthesize it out of smaller multiplies and divides, which is pretty much the same thing as implementing your own biginteger library.
If you can guarentee that c is small enough that (c-1)*(c-1) will not overflow an unsigned, you could use:
unsigned muldiv(unsigned a, unsigned b, unsigned c) {
return (a/c)*(b/c)*c + (a%c)*(b/c) + (a/c)*(b%c) + (a%c)*(b%c)/c;
}
This will actually give you the "correct" answer for ALL a and b -- (a * b)/c % (UINT_MAX+1)
To avoid overflow you have to pre-divide and then post-multiply by some factor.
The best factor to use is c, as long as one (or both) of a and b is greater than c. This is what Chris Dodd's function does. It has a greatest intermediate of ((a % c) * (b % c)), which, as Chris identifies, is less than or equal to ((c-1)*(c-1)).
If you could have a situation where both a and b are less than c, but (a * b) could still overflow, (which might be the case when c approaches the limit of the word size) then the best factor to use is a large power of two, to turn the multiply and divides into shifts. Try shifting by half the word size.
Note that using pre-divide and then post-multiplying is the equivalent of using longer words when you don't have longer words available. Assuming you don't discard the low order bits but just add them as another term, then you are just using several words instead of one larger one.
I'll let you fill the code in.
I understood how this solution works.
int add_no_arithm(int a, int b) {
if (b == 0) return a;
int sum = a ^ b; // add without carrying
int carry = (a & b) << 1; // carry, but don’t add
return add_no_arithm(sum, carry); // recurse
}
But the author comments over this problem as:
"Our first instinct in problems like these should be that we’re going to have to work with bits. Why? Because when you take away the + sign, what other choice do we have? Plus, that’s how computers do it."
What is the author trying to imply?
What he means is quite simple - if you don't have the + operation, you'll need to replicate the behaviour on the bit level of an integer. The code you posted is about the same of what the + operation does natively in the ALU (algorithmic logical unit, the place where calculations take place in a CPU).
Yeah, this is what is used - http://en.wikipedia.org/wiki/Adder_%28electronics%29