使用位运算符乘法 [英] Multiplying using Bitwise Operators

查看:201
本文介绍了使用位运算符乘法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道我怎么能去乘以一系列使用位运算符二进制位。不过,我很感兴趣,这样做是为了找到二进制值的小数部分的价值。这里是什么我试图做一个例子:

I was wondering how I could go about multiplying a series of binary bits using bitwise operators. However, I'm interested in doing this to find the a decimal fraction value for the binary value. Here's an example of what I'm trying to do:

考虑,说:1010010,

Given, say: 1010010,

我要使用的每个单独的位,这样它会被计算为:

I want to use each individual bit so that it will be computed as:

1 *(2 ^ 1)+ 0 *(2 ^ -2)+ 1 *(2 ^ 3)+ 0 *(2 ^ -4).....

1*(2^-1) + 0*(2^-2) + 1*(2^-3) + 0*(2^-4).....

虽然我很感兴趣,在ARM汇编这样做,具有C / C ++的例子仍然会有所帮助。

Though I'm interested in doing this in ARM assembly, having an example in C/C++ will still help as well.

我想用一个计数器,其中每个时间循环迭代,计数器递增执行一个循环,该值将被逻辑左移,使得第一位将被采取,并且由2 ^γ-计数器相乘。

I was thinking of performing a loop with a counter, where each time the loop iterates, a counter will increment, the value will be logically shifted left so that the first bit will be taken, and multiplied by 2^-counter.

不过,我不能完全肯定我将如何去刚开只是第位/ MSB倍增,和我很困惑,我怎么会被基地2乘以该值来一些负面力量。

However, I'm not entirely sure how I would go about just getting just the first bit/MSB to multiply, and I'm confused as to how I would multiply that value by base 2 to some negative power.

我知道,逻辑移位左派将与基地二期相乘,但这些通常有正指数。防爆。 LSL R0,2表示R0中的值将被乘以2 ^ 2 = 4。

I know that logical shift lefts will multiply it with base two, but those usually have positive exponents. Ex. LSL r0, 2 means the value in r0 will be multiplied by 2^2 = 4.

在此先感谢!

推荐答案

这听起来像你在正确的轨道上......只是做了。

it sounds like you are on the right track...just do it.

如果我有这些二进制数字,我乘

if I have these binary numbers I am multiplying

  abcd
* 1011
=======

其中A,B,C,D都只是位,这件事不只是还没有,你会看到一个或零,为什么

where a, b, c, d are just bits, one or zero which dont matter just yet as you will see why

1011如你所知道的是1 *(2 ^ 0)+1(2 ^ 1)+ 0 *(2 ^ 2)+1(2 ^ 3)。

1011 as you know is 1*(2^0)+1(2^1)+0*(2^2)+1(2^3).

酷似小学数学,但简单,因为我们只关心1和0,而不是9比0 ..

exactly like grade school math, but simpler since we only care about 1 and 0 and not 9 to 0..

     abcd
   * 1011
   =======
     abcd  (abcd * 1 * 2^0)
    0000   (abcd * 1 * 2^1)
   abcd    (abcd * 0 * 2^2)
+ abcd     (abcd * 1 * 2^3)
==========

如果灯泡剪掉熄灭尚未然后

and if the light bulb didnt go off yet then

     abcd
   * 1011
   =======
     abcd  (abcd << 0)
    00000  (abcd << 1)
   abcd00  (0 << 2)
+ abcd000  (abcd << 3)
==========

然后添加了这些值。

Then you add up those values.

unsigned long long mymult ( unsigned int a, unsigned int b )
{
    unsigned long long ra;
    unsigned int rb;
    ra=0;
    for(rb=0;rb<32;rb++)
    { 
        if(b&(1<<rb)) ra+=(unsigned long long a)<<rb;
    }
}

这应该是pretty容易组装来实现。用一个简单的计算器(以及使用一个,它的十六进制),你可以很快看到,0xFF的*为0xFF = 0xFE01,如果你不断尝试的事情,你应该意识到它可能需要两倍的位作为操作数的宽度保存结果。如果将两个8位数字,以处理所有可能的组合需要一个16位的结果。现在,有一个乘法不要太多的处理器实际上做到这样使得处理器成倍有点没用的海事组织。所以,你可以选择做一个简单的32位= 32位* 32位,或者你可以尝试一些像上面做一个64位= 32位* 32位(假设编译器间$ P $点的长的长度和int我假定他们是)。你可能要开始与32位= 32位* 32位,并从那里走。它得到pretty棘手除此之外,另外一个话题。 (这也可以很容易地模拟了一个C的例子,相当琐碎但不作为平凡的,因为这下面)。

Which should be pretty easy to implement in assembly. Using a simple calculator (well using one that does hex) you can very quickly see that 0xFF * 0xFF = 0xFE01, and if you keep trying things you should realize that it can take up to twice as many bits as the width of the operand to hold the result. If you multiply two 8 bit numbers, to handle all the possible combinations you need a 16 bit results. Now too many processors that have a multiply dont actually do it that way making the processors multiply somewhat useless IMO. So you can choose to do a simple 32 bit = 32bit * 32 bit, or you can try something like above and do a 64 bit = 32 bit * 32bit (assuming the compiler interprets the lengths of long and int as I assume them to be). You might want to start with 32 bit = 32 bit * 32 bit and go from there. it gets pretty tricky beyond that, another topic. (which can also be easily modeled in a C example, fairly trivial but not as trivial as this below).

unsigned int mymult ( unsigned int a, unsigned int b )
{
    unsigned int ra;
    unsigned int rb;
    ra=0;
    for(rb=0;rb<32;rb++)
    { 
        if(b&(1<<rb)) ra+=a<<rb;
    }
}

负的权力?如果2 ^ 4的手段左移以及4然后2 ^( - 4)将意味着右移4是吗?覆盖消极的权力。

Negative powers? well if 2^4 means shift left 4 then 2^(-4) would mean shift right 4 yes? that covers negative powers.

就像浮点需要任意选择您的小数点和规范它。所以,如果你想分数的4位和整数然后28位,如果你想乘5 *您需要这些数字调整至5℃7; 4; 7&LT;&4;它们归到你的小数点位置。 0b1010000和0b1110000乘法给出结果0b1000110000。 35(0x23),无级分。第一比特到您的假想小数点的右边是2 ^ -1或1/2,在接下来的比特是2 ^ -2或1/4等等。

Just like floating point you need to arbitrarily choose where your decimal point is and normalize to it. So if you want 4 bits of fraction and 28 bits of whole number then if you want to multiply 5 * 7 you need to adjust those numbers to 5<<4 and 7<<4 normalizing them to your decimal location. 0b1010000 and 0b1110000 multiplying gives the result 0b1000110000. 35 (0x23) with no fraction. the first bit to the right of your imaginary decimal point is 2^-1 or 1/2, the next bit over is 2^-2 or 1/4th and so on.

这是点如何浮动的作品,但它与大多数数字的肉基本上没有在一个科学记数法风格小数点的右侧。就像从初中或高中科学记数法的数学,你必须遵循之前和简单的数学操作后,preparing你的号码的规则。指数必须匹配之前,你可以添加例如,乘他们不,但你增加指数以及乘号部分...

This is how floating point works but it does it basically in a scientific notation style with most of the meat of the number to the right of the decimal place. Just like scientific notation math from middle or high school you have to follow those rules for preparing your numbers before and after the simple math operation. exponents have to match before you can add for example, multiplication they dont but you add the exponents as well as multiply the number portion...

这篇关于使用位运算符乘法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆