-2

I saw in one of the sites an interview question in C, which you are asked to write a function which get 2 integers, num and times, and multiple them without using the * operator, meaning using mainly shift left and right. I came up with a working answer (unless anyone finds a bug), but does anyone has a better way solving it in better time or memory consumption?

here is what I wrote:

#include <stdio.h>

int multiply_with_shift (int num, int times)
{
   int cnt=0;
   int org_times=times;
   if((num & times)==0)
       return 0;
   else
   {
   while(times >1)   
   {
      times=  times >> 1;
      cnt++;
   }
   int val= 1;
      val= val <<cnt;              
   int sub= org_times-val;         
   int res= num << cnt;            
   for( int i=0 ; i < sub; i++)    
   {
      res+=num;
   }
      return res;
   }
}


void main()
{
    int tmp;
    tmp=multiply_with_shift(5,15);
    printf(" the answer is : %d \n", tmp);
    printf("\n");
}

?

Ian Goldby
  • 5,609
  • 1
  • 45
  • 81
KBE
  • 379
  • 3
  • 4
  • 15

2 Answers2

5

Here's a more concise and bugfree (I believe) implementation, that doesn't even invoke undefined behavior:

unsigned mul(unsigned a, unsigned b)
{
    unsigned acc = 0;
    while (b) {
        if (b & 1) acc += a;
        b >>= 1;
        a <<= 1;
    }
    return acc;
}

Your code had several flaws:

  1. readability, length, etc...
  2. if ((num & times) == 0) return 0; -> this would return 0 for numbers of which don't share at least one common power of two in their binary representation, i. e. 4 * 8 = 0.
  3. Shifting in the sign bit is undefined behavior in C - you need to use unsigned integers for this task.
  • `` *The comments under this answer were obsolete, or pure noise and have subsequently been removed. Please keep comments constructive, professional and on topic.* – Tim Post Feb 13 '13 at 15:34
  • 1
    @TimPost OneManCrew accused me of something I didn't do. That's unfair. –  Feb 13 '13 at 15:42
  • @H2CO3 I realy liked your answer, couldn't find a bug and it deals with all kinds of integers such as 2^n and zero. do you have any idea how to deal with signed integers also? – KBE Feb 14 '13 at 13:25
  • @KBE MatsPetersson's solution deals with signed integers as well (but you can just XOR `a < 0` and `b < 0` anyway). –  Feb 14 '13 at 13:57
0

If you want a signed integer variant, this would work:

int mul(int a, int b)
{
    sign = (a ^ b) >> (sizeof(a) * CHAR_BIT - 1);
    if (a > 0)
        a = -a;
    if (b > 0)
        b = -b;
    int acc = 0;
    while (b) {
        if (b & 1) acc += a;
        b >>= 1;
        a <<= 1;
    }
    if (sign) acc = -acc;
    return acc;
}

[Credit to H2CO3's implementation in another post for most of the algorithm]

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227