Как выполнить умножение, используя побитовые операторы?

StackOverflow https://stackoverflow.com/questions/3722004

  •  03-10-2019
  •  | 
  •  

Вопрос

Я работаю над проблемой, которую мне удалось решить, за исключением последней части - я не уверен, как можно выполнить умножение с использованием побитовых операторов:

0*8 = 0

1*8 = 8

2*8 = 16 

3*8 = 24 

4*8 = 32

Не могли бы вы, пожалуйста, порекомендовать подход к решению этой проблемы?

Это было полезно?

Решение

Умножить на любое значение, равное 2 , в степени N (т. е.2^ N) сдвиньте биты N раз влево.

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

и т.д..

Чтобы разделить, сдвиньте биты вправо.

Биты являются целыми 1 или 0 - вы не можете сдвинуться на часть бита, поэтому, если число, на которое вы умножаете, не учитывает целое значение N ie.

since: 17 = 16  + 1 
thus:  17 = 2^4 + 1

therefore: x * 17 = (x * 16) + x in other words 17 x's  

таким образом, чтобы умножить на 17, вам нужно сделать 4-битный сдвиг влево, а затем снова добавить исходное число:

==> 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)

т.е.

    0011 0000  (48)  
+   0000 0011   (3)
=============
    0011 0011  (51)

Редактировать:Обновите исходный ответ. Чарльз Петцольд написал фантастическую книгу "Код" это объяснит все это и многое другое самым простым способом.Я настоятельно рекомендую это.

Другие советы

Умножить два двоичных закодированных номера без размноженного инструкции. Было бы просто до достижения продукта.

unsigned int mult(x, y)
unsigned int x, y;
{
    unsigned int reg = 0;

    while(y--)
        reg += x;
    return reg;
}

Использование битовых операций, характеристика кодировки данных может быть использована. Как объяснено ранее, битовый сдвиг такой же, как умножение на два. Использование этого сумматор можно использовать на мощности двух.

// 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;
}

Я считаю, что это должно быть левый сдвиг. 8 - 2 ^ 3, поэтому левый сдвиг 3 бита:

2 << 3 = 8

Вы учитываете многопользовательскую и в мощности 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;
    }
-(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;
}

Я только что понял, что это тот же ответ, что и предыдущий. LOL извините.

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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top