如何使用按位运算符执行乘法?

问题描述 投票:0回答:10

我正在解决一个我能够解决的问题,除了最后一部分之外,我不确定如何使用按位运算符进行乘法:

0*8 = 0

1*8 = 8

2*8 = 16 

3*8 = 24 

4*8 = 32

有办法解决这个问题吗?

bit-manipulation multiplication
10个回答
52
投票

要乘以 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 的整个值。 即,

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

即,

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

Charles Petzold 写了一本精彩的书《代码》,它将以最简单的方式解释所有这些以及更多内容。我强烈推荐这个。


18
投票

无需乘法指令即可将两个二进制编码数相乘。 迭代添加以达到产品会很简单。

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

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

使用位运算,可以利用数据编码的特性。 如前所述,位移位与乘以 2 相同。 使用这个加法器可以用于 2 的幂。

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

3
投票

您可以将被乘数分解为 2 的幂。
3*17 = 3*(16+1) = 3*16 + 3*1 ... = 0011b << 4 + 0011b


3
投票
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;
    }

1
投票

我相信这应该是左移。 8 是 2^3,所以左移 3 位:

2<< 3 = 8


0
投票
-(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;
}

0
投票

我刚刚意识到这与上一个答案相同。哈哈,抱歉。

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

0
投票

我正在研究一个没有

*
运算符的递归乘法问题,并提出了一个由此处最佳答案告知的解决方案。

我认为值得发布,因为我真的很喜欢这里最佳答案中的解释,但想以这样的方式扩展它:

  1. 有一个函数表示。
  2. 处理“余数”任意的情况。

这仅处理正整数,但您可以将其包装在对负数的检查中,就像其他一些答案一样。

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)

0
投票

使用按位运算符降低时间复杂度。

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

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)

-1
投票
def multiply(x, y):
     return x << (y >> 1)

您可能希望将 y 的值减半,因此 y 将位向右移动一次 (y >> 1),然后再向左移动 x 次以获得答案 x << (y >> 1)。

© www.soinside.com 2019 - 2024. All rights reserved.