'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?
Solution 1:[1]
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.
Solution 2:[2]
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;
}
Solution 3:[3]
You'd factor the multiplicand into powers of 2.
3*17 = 3*(16+1) = 3*16 + 3*1
... = 0011b << 4 + 0011b
Solution 4:[4]
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;
}
Solution 5:[5]
I believe this should be a left shift. 8 is 2^3, so left shift 3 bits:
2 << 3 = 8
Solution 6:[6]
-(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;
}
Solution 7:[7]
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;
}
Solution 8:[8]
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)
Solution 9:[9]
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)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Ivan Ferić |
| Solution 3 | epic_fil |
| Solution 4 | Algorithmatic |
| Solution 5 | Jeff Ogata |
| Solution 6 | muzz |
| Solution 7 | Nicolas |
| Solution 8 | |
| Solution 9 | Harsha Sri Sameera |
