The fast version. It can be tweaked, but anyone have a better core approach?
what it does is create a bit shifter, i, which is 1,2,4,8,... etc powers of 2.
it then keeps a running addition of b. that is, when i is 1, its b. when i = 2, its b+b. When i = 4, its b+b+b+b. and so on. the sum you want is the bits of b related to that sum, eg if b were 5, which in binary is 4+1, you want (b+b+b+b) + b. Or in the code, it adds the zeros too (faster than checking), so its (b+b+b+b) +0(2's bit is zero)+ b
just like doing integer powers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
long long p(long long a, long long b)
{
long long r = 0;
long long zero = 0;
long long a2 = abs(a);
long long b2 = abs(b);
if( (a < 0 && b > 0) || (a>0 && b < 0))
a2 = -a2;
long long* t[2] = {&a2, &zero};
for(long long i = 1; i <= 9223372036854775808ull && b2 >= i; i= i << 1)
{
r += t[((unsigned long long)b2&(unsigned long long)i)==0][0];
a2+=a2;
}
return r;
}
int main()
{
cout << p(50000,-50000)<< endl; //does less than 64 additions. I think 16 for this example
cout << p(3,-5)<< endl;
cout << p(-3,5)<< endl;
cout << p(3,5)<< endl;
cout << p(0,-5)<< endl;
cout << p(4,0)<< endl;
}
|
See if you can understand this. I don't advise turning it in, but if you can see how to do this, you will be way ahead of the class.