For the classic interview question “How do you perform integer multiplication without the multiplication operator?”, the easiest answer is, of course, the following linear-time algorithm in C:
int mult(int multiplicand, int multiplier)
{
for (int i = 1; i < multiplier; i++)
{
multiplicand += multiplicand;
}
return multiplicand;
}
Of course, there is a faster algorithm. If we take advantage of the property that bit shifting to the left is equivalent to multiplying by 2 to the power of the number of bits shifted, we can bit-shift up to the nearest power of 2, and use our previous algorithm to add up from there. So, our code would now look something like this:
#include <math.h>
int log2( double n )
{
return log(n) / log(2);
}
int mult(int multiplicand, int multiplier)
{
int nearest_power = 2 ^ (floor(log2(multiplier)));
multiplicand << nearest_power;
for (int i = nearest_power; i < multiplier; i++)
{
multiplicand += multiplicand;
}
return multiplicand;
}
I’m having trouble determining what the time complexity of this algorithm is. I don’t believe that O(n - 2^(floor(log2(n)))) is the correct way to express this, although (I think?) it’s technically correct. Can anyone provide some insight on this?
mulitplier - nearest_powercan be as large as half ofmultiplier, and as it tends towards infinity the constant0.5there doesn’t matter (not to mention we get rid of constants in Big O). The loop is thereforeO(multiplier). I’m not sure about the bit-shifting.Edit: I took more of a look around on the bit-shifting. As gbulmer says, it can be
O(n), wherenis the number of bits shifted. However, it can also beO(1)on certain architectures. See: Is bit shifting O(1) or O(n)?However, it doesn’t matter in this case!
n > log2(n)for all validn. So we haveO(n) + O(multiplier)which is a subset ofO(2*multiplier)due to the aforementioned relationship, and thus the whole algorithm isO(multiplier).