C++ Sieve of Atkin overlooks a few prime numbers - c++

Recently I've been working on a C++ prime generator that uses the Sieve of Atkin ( http://en.wikipedia.org/wiki/Sieve_of_atkin ) to generate its primes. My objective is to be able to generate any 32-bit number. I'll use it mostly for project euler problems. mostly it's just a summer project.
The program uses a bitboard to store primality: that is, a series of ones and zeros where for example the 11th bit would be a 1, the 12th a 0, and the 13th a 1, etc. For efficient memory usage, this is actually and array of chars, each char containing 8 bits. I use flags and bitwise-operators to set and retrieve bits. The gyst of the algorithm is simple: do a first pass using some equations I don't pretend to understand to define if a number is considered "prime" or not. This will for the most part get the correct answers, but a couple nonprime numbers will be marked as prime. Therefore, when iterating through the list, you set all multiples of the prime you just found to "not prime". This has the handy advantage of requiring less processor time the larger a prime gets.
I've got it 90% complete, with one catch:
some of the primes are missing.
Through inspecting the bitboard, I have ascertained that these primes are omitted during the first pass, which basically toggles a number for every solution it has for a number of equations (see wikipedia entry). I've gone over this chunk of code time and time again. I even tried increasing the bounds to what is shown in the wikipedia articles, which is less efficient but I figured might hit a few numbers that I have somehow omitted. Nothing has worked. These numbers simply evaluate to not prime. Most of my test has been on all primes under 128. Of this range, these are the primes that are omitted:
23 and 59.
I have no doubt that on a higher range, more would be missing (just don't want to count through all of them). I don't know why these are missing, but they are. Is there anything special about these two primes? I've double and triple checked, finding and fixing mistakes, but it is still probably something stupid that I am missing.
anyways, here is my code:
#include <iostream>
#include <limits.h>
#include <math.h>
using namespace std;
const unsigned short DWORD_BITS = 8;
unsigned char flag(const unsigned char);
void printBinary(unsigned char);
class PrimeGen
{
public:
unsigned char* sieve;
unsigned sievelen;
unsigned limit;
unsigned bookmark;
PrimeGen(const unsigned);
void firstPass();
unsigned next();
bool getBit(const unsigned);
void onBit(const unsigned);
void offBit(const unsigned);
void switchBit(const unsigned);
void printBoard();
};
PrimeGen::PrimeGen(const unsigned max_num)
{
limit = max_num;
sievelen = limit / DWORD_BITS + 1;
bookmark = 0;
sieve = (unsigned char*) malloc(sievelen);
for (unsigned i = 0; i < sievelen; i++) {sieve[i] = 0;}
firstPass();
}
inline bool PrimeGen::getBit(const unsigned index)
{
return sieve[index/DWORD_BITS] & flag(index%DWORD_BITS);
}
inline void PrimeGen::onBit(const unsigned index)
{
sieve[index/DWORD_BITS] |= flag(index%DWORD_BITS);
}
inline void PrimeGen::offBit(const unsigned index)
{
sieve[index/DWORD_BITS] &= ~flag(index%DWORD_BITS);
}
inline void PrimeGen::switchBit(const unsigned index)
{
sieve[index/DWORD_BITS] ^= flag(index%DWORD_BITS);
}
void PrimeGen::firstPass()
{
unsigned nmod,n,x,y,xroof, yroof;
//n = 4x^2 + y^2
xroof = (unsigned) sqrt(((double)(limit - 1)) / 4);
for(x = 1; x <= xroof; x++){
yroof = (unsigned) sqrt((double)(limit - 4 * x * x));
for(y = 1; y <= yroof; y++){
n = (4 * x * x) + (y * y);
nmod = n % 12;
if (nmod == 1 || nmod == 5){
switchBit(n);
}
}
}
xroof = (unsigned) sqrt(((double)(limit - 1)) / 3);
for(x = 1; x <= xroof; x++){
yroof = (unsigned) sqrt((double)(limit - 3 * x * x));
for(y = 1; y <= yroof; y++){
n = (3 * x * x) + (y * y);
nmod = n % 12;
if (nmod == 7){
switchBit(n);
}
}
}
xroof = (unsigned) sqrt(((double)(limit + 1)) / 3);
for(x = 1; x <= xroof; x++){
yroof = (unsigned) sqrt((double)(3 * x * x - 1));
for(y = 1; y <= yroof; y++){
n = (3 * x * x) - (y * y);
nmod = n % 12;
if (nmod == 11){
switchBit(n);
}
}
}
}
unsigned PrimeGen::next()
{
while (bookmark <= limit)
{
bookmark++;
if (getBit(bookmark))
{
unsigned out = bookmark;
for(unsigned num = bookmark * 2; num <= limit; num += bookmark)
{
offBit(num);
}
return out;
}
}
return 0;
}
inline void PrimeGen::printBoard()
{
for(unsigned i = 0; i < sievelen; i++)
{
if (i % 4 == 0)
cout << endl;
printBinary(sieve[i]);
cout << " ";
}
}
inline unsigned char flag(const unsigned char bit_index)
{
return ((unsigned char) 128) >> bit_index;
}
inline void printBinary(unsigned char byte)
{
unsigned int i = 1 << (sizeof(byte) * 8 - 1);
while (i > 0) {
if (byte & i)
cout << "1";
else
cout << "0";
i >>= 1;
}
}
I did my best to clean it up and make it readable. I'm not a professional programmer, so please be merciful.
Here is the output I get, when I initialize a PrimeGen object named pgen, print its initial bitboard with pgen.printBoard() (please note that 23 and 59 are missing before next() iteration), and then iterate through next() and print all of the returned primes:
00000101 00010100 01010000 01000101
00000100 01010001 00000100 00000100
00010001 01000001 00010000 01000000
01000101 00010100 01000000 00000001
5
7
11
13
17
19
29
31
37
41
43
47
53
61
67
71
73
79
83
89
97
101
103
107
109
113
127
DONE
Process returned 0 (0x0) execution time : 0.064 s
Press any key to continue.

Eureka!!!
As expected, it was a stupid error on my part.
The 3x^2 - y^2 equation has a small caveat that I overlooked: x > y. With this taken into account, I was switching 23 and 59 too many times, leading to them failing.
Thanks for all the help you guys. Saved my bacon.

Related

Generate all combinations in bit version

I'd like to generate all possible combination (without repetitions) in bit representation. I can't use any library like boost or stl::next_combination - it has to be my own code (computation time is very important).
Here's my code (modified from ones StackOverflow user):
int combination = (1 << k) - 1;
int new_combination = 0;
int change = 0;
while (true)
{
// return next combination
cout << combination << endl;
// find first index to update
int indexToUpdate = k;
while (indexToUpdate > 0 && GetBitPositionByNr(combination, indexToUpdate)>= n - k + indexToUpdate)
indexToUpdate--;
if (indexToUpdate == 1) change = 1; // move all bites to the left by one position
if (indexToUpdate <= 0) break; // done
// update combination indices
new_combination = 0;
for (int combIndex = GetBitPositionByNr(combination, indexToUpdate) - 1; indexToUpdate <= k; indexToUpdate++, combIndex++)
{
if(change)
{
new_combination |= (1 << (combIndex + 1));
}
else
{
combination = combination & (~(1 << combIndex));
combination |= (1 << (combIndex + 1));
}
}
if(change) combination = new_combination;
change = 0;
}
where n - all elements, k - number of elements in combination.
GetBitPositionByNr - return position of k-th bit.
GetBitPositionByNr(13,2) = 3 cause 13 is 1101 and second bit is on third position.
It gives me correct output for n=4, k=2 which is:
0011 (3 - decimal representation - printed value)
0101 (5)
1001 (9)
0110 (6)
1010 (10)
1100 (12)
Also it gives me correct output for k=1 and k=4, but gives me wrong outpu for k=3 which is:
0111 (7)
1011 (11)
1011 (9) - wrong, should be 13
1110 (14)
I guess the problem is in inner while condition (second) but I don't know how to fix this.
Maybe some of you know better (faster) algorithm to do want I want to achieve? It can't use additional memory (arrays).
Here is code to run on ideone: IDEONE
When in doubt, use brute force. Alas, generate all variations with repetition, then filter out the unnecessary patterns:
unsigned bit_count(unsigned n)
{
unsigned i = 0;
while (n) {
i += n & 1;
n >>= 1;
}
return i;
}
int main()
{
std::vector<unsigned> combs;
const unsigned N = 4;
const unsigned K = 3;
for (int i = 0; i < (1 << N); i++) {
if (bit_count(i) == K) {
combs.push_back(i);
}
}
// and print 'combs' here
}
Edit: Someone else already pointed out a solution without filtering and brute force, but I'm still going to give you a few hints about this algorithm:
most compilers offer some sort of intrinsic population count function. I know of GCC and Clang which have __builtin_popcount(). Using this intrinsic function, I was able to double the speed of the code.
Since you seem to be working on GPUs, you can parallelize the code. I have done it using C++11's standard threading facilities, and I've managed to compute all 32-bit repetitions for arbitrarily-chosen popcounts 1, 16 and 19 in 7.1 seconds on my 8-core Intel machine.
Here's the final code I've written:
#include <vector>
#include <cstdio>
#include <thread>
#include <utility>
#include <future>
unsigned popcount_range(unsigned popcount, unsigned long min, unsigned long max)
{
unsigned n = 0;
for (unsigned long i = min; i < max; i++) {
n += __builtin_popcount(i) == popcount;
}
return n;
}
int main()
{
const unsigned N = 32;
const unsigned K = 16;
const unsigned N_cores = 8;
const unsigned long Max = 1ul << N;
const unsigned long N_per_core = Max / N_cores;
std::vector<std::future<unsigned>> v;
for (unsigned core = 0; core < N_cores; core++) {
unsigned long core_min = N_per_core * core;
unsigned long core_max = core_min + N_per_core;
auto fut = std::async(
std::launch::async,
popcount_range,
K,
core_min,
core_max
);
v.push_back(std::move(fut));
}
unsigned final_count = 0;
for (auto &fut : v) {
final_count += fut.get();
}
printf("%u\n", final_count);
return 0;
}

Multiplying integers the long way

I'm trying to create long int multiplication function. In math for multiplying 2 numbers for example 123 X 456, I do:
(12 * 10^1 + 3)( 45 * 10^1 + 6) =
(540 * 10^2) + (72 * 10^1) + (135 * 10^1) + 18 = 15129
I created a small program for this algorithm but it didn't work right.
I don't know where my problem is. Can you help me to understand and correct that?
Tnx
int digits(int n) {
int digit = 0;
while (n>0){
n/=10;
digit++;
}
return digit;
}
long int longMult(long int a, long int b) {
long int x,y,w,z;
int digitA = digits(a);
int digitB = digits(b);
if((a==0) || (b==0)) {
return 0;
} else if (digitA < 2 || digitB < 2) {
return a*b;
} else {
int powA = digitA / 2;
int powB = digitB / 2;
//for first number
x = a/(10^powA);
y = a%(10^powA);
//for second number
w = b/(10^powB);
z = b%(10^powB);
return ( longMult(x,w)*(10^(powA*powB)) + longMult(x,z) +
longMult(w,y)*(10^(powA*powB)) + longMult(y,z));
}
}
int main()
{
cout << digits(23) << endl; // for test
cout << longMult(24,24); // must be 576 but output is 96
return 0;
}
The expression
10^powA
does a bitwise exclusive or, and doesn't raise 10 to the power of powA, as you appear to expect.
You may want to define something like
long powli(int b, long e) {return e?b*powli(b,e-1):1;}
Then instead you can use
powli(10,powA)
Edit: There is also a problem with the way the values are combined:
return ( longMult(x,w)*(10^(powA*powB)) + longMult(x,z) +
longMult(w,y)*(10^(powA*powB)) + longMult(y,z));
Look into the maths, because multiplying the exponents makes little sense.
Also the combinations of adjustments to values is wrong, eg (10*a + b)(10*c + d) = 10*10*a*c + 10*a*d + 10*b*d +b*d. So check on your algebra.

I want to determine the nth Fibonacci term in the sequence using large integer values

The code below is able to determine the correct sequence up to a point namely 70 using the data type unsigned long long. I know the sequence can become large thus I mod 10,000 the results. I want to determine the nth term for 10,000 using the best data type or improve the algo to calculate the nth term.
#define MOD %10000
unsigned long long calc(long nth) {
return (pow( 1 + sqrt(5), nth ) - pow( 1 - sqrt(5), nth )) / (pow(2.0, nth)*(sqrt(5)));
}
int main() {
long t, nth;
for (std::cin>>t; t-- && std::cin>>nth; ) {
std::cout<<calc(nth-2)MOD<<" "<<calc(nth-1)MOD<<" "<<calc(nth)MOD<<std::endl;
}
return 0;
}
Your algorithm will not compute the correct result for large N's, due to the floating point errors of sqrn(5).
In order to speed up your algorithm you can use fast doubling Fibonacci:
F(2k) = F(k)[2F(k+1) - F(k)]
F(2k+1) = F(k+1)^2 + F(k)^2
Applying modulo arithmetics, your final fastest algorithm would be:
F(2k) = F(k)[2F(k+1) - F(k)] % 10000
F(2k+1) = (F(k+1)^2 + F(k)^2) % 10000
Using this approach, your function never exceeds 10000, thus an int type suffices.
EDIT: Okay I had some free time on a Friday night (not a good thing I guess) and implemented the algorithm. I implemented two versions, first one with O(1) memory and O(lg n) time complexity and second one using a cache, with memory and worst-case runtime of O(lg n), but with a best case runtime of O(1).
#include <iostream>
#include <unordered_map>
using namespace std;
const int P = 10000;
/* Fast Fibonacci with O(1) memory and O(lg n) time complexity. No cache. */
int fib_uncached (int n)
{
/* find MSB position */
int msb_position = 31;
while (!((1 << (msb_position-1) & n)) && msb_position >= 0)
msb_position--;
int a=0, b=1;
for (int i=msb_position; i>=0;i--)
{
int d = (a%P) * ((b%P)*2 - (a%P) + P),
e = (a%P) * (a%P) + (b%P)*(b%P);
a=d%P;
b=e%P;
if (((n >> i) & 1) != 0)
{
int c = (a + b) % P;
a = b;
b = c;
}
}
return a;
}
/* Fast Fibonacci using cache */
int fib (int n)
{
static std::unordered_map<int,int> cache;
if (cache.find(n) == cache.end())
{
int f;
if (n==0)
f = 0;
else if (n < 3)
f = 1;
else if (n % 2 == 0)
{
int k = n/2;
f = (fib(k) * (2*fib(k+1) - fib(k))) % P;
}
else
{
int k = (n-1)/2;
f = (fib(k+1)*fib(k+1)+ fib(k) * fib(k)) % P;
}
if (f<0)
f += P;
cache[n] = f;
}
return cache.at(n);
}
int main ()
{
int i ;
cin >> i;
cout << i << " : " << fib(i) << endl;
return 0;
}
Reference for cache-less implementations: https://www.nayuki.io/page/fast-fibonacci-algorithms
Calculate the terms successively, taking the mod at each step. Since each term only depends on the previous two, your computational space is just a 3-element array.
#include <iostream>
using namespace std;
typedef unsigned long long numtype;
const numtype MOD = 10000;
// Assume n is 1-based
numtype fib(int n)
{
numtype seq[3] = {1,1,2};
if( --n < 3 ) return seq[n]; // make n 0-based
for( int i=3 ; i<=n ; ++i )
{
seq[i%3] = (seq[(i-1)%3] + seq[(i-2)%3]) % MOD;
cout << seq[i%3] << ' '; // comment out for large n
}
return seq[n%3];
}
int main()
{
//numtype answer = fib(10000000); // 6875
numtype answer = fib(70); // 9135
cout << endl;
cout << "answer = " << answer << endl;
}
Output:
3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 946 7711 8657 6368 5025 1393 6418 7811 4229 2040 6269 8309 4578 2887 7465 352 7817 8169 5986 4155 141 4296 4437 8733 3170 1903 5073 6976 2049 9025 1074 99 1173 1272 2445 3717 6162 9879 6041 5920 1961 7881 9842 7723 7565 5288 2853 8141 994 9135
(The first 3 terms 1,1,2 are intentionally missing.) The 70th term is 9135.
Time is O(n) and memory is O(1).

How to reduce time complexity for large data set inputs in this program?

I have written this code to calculate the number of set bits between the range of numbers. My program gets compiled fine and giving proper output. It is taking too much time for large inputs and "Time limit exceeding".
#define forn(i, n) for(long int i = 0; i < (long int)(n); i++)
#define ford(i, n) for(long int i = (long int)(n) - 1; i >= 0; i--)
#define fore(i, a, n) for(long int i = (int)(a); i < (long int)(n); i++)
long int solve(long int i) {
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
int main() {
freopen("C:/Projects/CodeChef/SetBits/input.txt", "rt", stdin);
freopen("C:/Projects/CodeChef/SetBits/output.txt", "wt", stdout);
int tt;
long long int num1;
long long int num2;
scanf("%d", &tt);
forn(ii, tt) {
unsigned long int bits = 0;
unsigned long long int total_bits = 0;
scanf("%lld",&num1);
scanf("%lld",&num2);
fore(jj, num1, num2+1) {
bits = solve(jj);
total_bits += bits;
}
printf("%lld\n",total_bits);
}
return 0;
}
Example test case:-
Sample Input:
3
-2 0
-3 4
-1 4
Sample Output:
63
99
37
For the first case, -2 contains 31 1's followed by a 0, -1 contains 32 1's and 0 contains 0 1's. Thus the total is 63.
For the second case, the answer is 31 + 31 + 32 + 0 + 1 + 1 + 2 + 1 = 99
Test case having large values:-
10
-1548535525 662630637
-1677484556 -399596060
-2111785037 1953091095
643110128 1917824721
-1807916951 491608908
-1536297104 1976838237
-1891897587 -736733635
-2088577104 353890389
-2081420990 819160807
-1585188028 2053582020
Any suggestions on how to optimize the code so that it will take less time. All helpful suggestions and answers will be appreciated with vote up. :)
I don't really have a clue what you are doing, but I do know you can clean up your code considerable, and you can inline you function.
Also I have taken the liberty of 'rephrasing' you code, you are using C++ like C and those defines are just grim and mapping the files onto stdio is even worse. I haven't tested or compiled the code but it is all there.
#include <fstream>
inline long int solve(long int i) {
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
int main() {
long first, last;
unsigned count;
std::ifstream inf("C:/Projects/CodeChef/SetBits/input.txt");
std::ofstream off("C:/Projects/CodeChef/SetBits/output.txt");
inf >> count;
for(unsigned i=0u; i!=count; ++i) {
inf >> first >> last;
long total=0;
++last;
for(long t=first; t!=last; ++t) {
total+=solve(t);
}
off << total << '\n';
}
return 0;
}
A few ideas as to how you could be speed this up:
you could build a std::map of the computed values and if they have been previously processed then use them rather than recomputing.
do the same but store ranges rather than single values but that will be tricky.
you could see if a value exists in the map and increment through the map until there are no more preprocessed values in which case start processing them for the iteration.
check if there is a trivial sequence between on number and the next may be you could work out the first value then just increment it.
may there is a O(1) algorithm for such a sequence
Look at intel TBB and using something like tbb::parallel for to distribute the work over each core, because you are dealing with such a small about or memory then you should get a really good return with a large chunk size.

How to perform multiplication, using bitwise operators?

I am working through a problem which i was able to solve, all but for the last piece - i am not sure how can one do multiplication using bitwise operators:
0*8 = 0
1*8 = 8
2*8 = 16
3*8 = 24
4*8 = 32
Can you please recommend an approach to solve this?
To multiply by any value of 2 to the power of N (i.e. 2^N) shift the bits N times to the left.
0000 0001 = 1
times 4 = (2^2 => N = 2) = 2 bit shift : 0000 0100 = 4
times 8 = (2^3 -> N = 3) = 3 bit shift : 0010 0000 = 32
etc..
To divide shift the bits to the right.
The bits are whole 1 or 0 - you can't shift by a part of a bit thus if the number you're multiplying by is does not factor a whole value of N
ie.
since: 17 = 16 + 1
thus: 17 = 2^4 + 1
therefore: x * 17 = (x * 16) + x in other words 17 x's
thus to multiply by 17 you have to do a 4 bit shift to the left, and then add the original number again:
==> x * 17 = (x * 16) + x
==> x * 17 = (x * 2^4) + x
==> x * 17 = (x shifted to left by 4 bits) + x
so let x = 3 = 0000 0011
times 16 = (2^4 => N = 4) = 4 bit shift : 0011 0000 = 48
plus the x (0000 0011)
ie.
0011 0000 (48)
+ 0000 0011 (3)
=============
0011 0011 (51)
Edit: Update to the original answer. Charles Petzold has written a fantastic book 'Code' that will explain all of this and more in the easiest of ways. I thoroughly recommend this.
To multiply two binary encoded numbers without a multiply instruction.
It would be simple to iteratively add to reach the product.
unsigned int mult(x, y)
unsigned int x, y;
{
unsigned int reg = 0;
while(y--)
reg += x;
return reg;
}
Using bit operations, the characteristic of the data encoding can be exploited.
As explained previously, a bit shift is the same as multiply by two.
Using this an adder can be used on the powers of two.
// multiply two numbers with bit operations
unsigned int mult(x, y)
unsigned int x, y;
{
unsigned int reg = 0;
while (y != 0)
{
if (y & 1)
{
reg += x;
}
x <<= 1;
y >>= 1;
}
return reg;
}
You'd factor the multiplicand into powers of 2.
3*17 = 3*(16+1) = 3*16 + 3*1
... = 0011b << 4 + 0011b
public static int multi(int x, int y){
boolean neg = false;
if(x < 0 && y >= 0){
x = -x;
neg = true;
}
else if(y < 0 && x >= 0){
y = -y;
neg = true;
}else if( x < 0 && y < 0){
x = -x;
y = -y;
}
int res = 0;
while(y!=0){
if((y & 1) == 1) res += x;
x <<= 1;
y >>= 1;
}
return neg ? (-res) : res;
}
I believe this should be a left shift. 8 is 2^3, so left shift 3 bits:
2 << 3 = 8
-(int)multiplyNumber:(int)num1 withNumber:(int)num2
{
int mulResult =0;
int ithBit;
BOOL isNegativeSign = (num1<0 && num2>0) || (num1>0 && num2<0) ;
num1 = abs(num1);
num2 = abs(num2);
for(int i=0;i<sizeof(num2)*8;i++)
{
ithBit = num2 & (1<<i);
if(ithBit>0){
mulResult +=(num1<<i);
}
}
if (isNegativeSign) {
mulResult = ((~mulResult)+1 );
}
return mulResult;
}
I have just realized that this is the same answer as the previous one. LOL sorry.
public static uint Multiply(uint a, uint b)
{
uint c = 0;
while(b > 0)
{
c += ((b & 1) > 0) ? a : 0;
a <<= 1;
b >>= 1;
}
return c;
}
I was working on a recursive multiplication problem without the * operator and came up with a solution that was informed by the top answer here.
I thought it was worth posting because I really like the explanation in the top answer here, but wanted to expand on it in a way that:
Had a function representation.
Handled cases where your "remainder" was arbitrary.
This only handles positive integers, but you could wrap it in a check for negatives like some of the other answers.
def rec_mult_bitwise(a,b):
# Base cases for recursion
if b == 0:
return 0
if b == 1:
return a
# Get the most significant bit and the power of two it represents
msb = 1
pwr_of_2 = 0
while True:
next_msb = msb << 1
if next_msb > b:
break
pwr_of_2 += 1
msb = next_msb
if next_msb == b:
break
# To understand the return value, remember:
# 1: Left shifting by the power of two is the same as multiplying by the number itself (ie x*16=x<<4)
# 2: Once we've done that, we still need to multiply by the remainder, hence b - msb
return (a << pwr_of_2) + rec_mult_bitwise(a, b - msb)
Using Bitwise operator reduces the time complexity.
In cpp:
#include<iostream>
using name space std;
int main(){
int a, b, res = 0; // read the elements
cin>>a>>b;
// find the small number to reduce the iterations
small = (a<b)?a:b; // small number using terinary operator
big = (small^a)?a:b; // big number using bitwise XOR operator
while(small > 0)
{
if(small & 1)
{
res += big;
}
big = big << 1; // it increases the number << is big * (2 power of big)
small = small >> 1; // it decreases the number >> is small / (2 power of small)
}
cout<<res;
}
In Python:
a = int(input())
b = int(input())
res = 0
small = a if(a < b) else b
big = a if(small ^ a) else b
def multiplication(small, big):
res = 0
while small > 0:
if small & 1:
res += big
big = big << 1
small = small >> 1
return res
answer = multiplication(small, big)
print(answer)
def multiply(x, y):
return x << (y >> 1)
You would want to halve the value of y, hence y shift bits to the right once (y >> 1) and shift the bits again x times to the left to get your answer x << (y >> 1).