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

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

问题描述

我想知道如何使用逐位运算符乘以一系列二进制位。然而,我有兴趣这样做找到二进制值的十进制小数值。这里是我想要做的一个例子:



给定,说:1010010,



使用每个单独的位,使得它将被计算为:



1 *(2 ^ -1)+ 0 *(2 ^ -2)+ 1 *虽然我有兴趣在ARM汇编中做这个,但在C语言中有一个例子/ C ++仍然会有帮助。



我正在考虑用计数器执行循环,每次循环迭代时,计数器将递增,该值将向左逻辑移位,使第一位将乘以2 ^ - 计数器。



然而,我不完全确定我将如何去只是得到第一个位/ MSB乘,我很困惑,如何将该值乘以基数2到一些负功率。



我知道逻辑左移将乘以基数2,但是通常有正指数。例如, LSL r0,2表示r0中的值将乘以2 ^ 2 = 4。



提前感谢!

解决方案

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



如果我有这些二进制数我乘以

  abcd 
* 1011
=======

其中a,b,c,d只是位,一个或零, / p>

1011,你知道是1 *(2 ^ 0)+1(2 ^ 1)+ 0 *(2 ^ 2)+1(2 ^ 3) / p>

完全类似于小学数学,但更简单,因为我们只关心1和0而不是9到0 ..

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

如果灯泡没有熄灭,则

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

然后将这些值相加。

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

在程序集中应该很容易实现。使用一个简单的计算器(很好地使用一个执行十六进制),你可以很快看到0xFF * 0xFF = 0xFE01,如果你继续尝试的东西,你应该意识到,它可以占据两倍的操作数的宽度的位,保持结果。如果你乘以两个8位数字,处理所有可能的组合,你需要一个16位的结果。现在太多的处理器有一个乘法不会这样做,使处理器多少有点无用的IMO。所以你可以选择做一个简单的32位= 32位* 32位,或者你可以尝试类似上面的做一个64位= 32位* 32位(假设编译器解释long和int的长度,我假设他们是)。您可能需要从32位= 32位* 32位开始,然后从那里开始。它变得相当棘手的超越,另一个话题。 (它也可以很容易地模拟在一个C的例子,相当琐碎,但不是如下所示的微不足道的)。

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

负功率?如果2 ^ 4意味着左移4,则2 ^( - 4)意味着右移4是?



就像浮点一样,你需要任意选择小数点的位置并进行归一化。所以如果你想要4位分数和28位整数,那么如果你想乘以5 * 7,你需要调整这些数字到5<< 4和7<< 4规范化他们到你的小数位。 0b1010000和0b1110000相乘得到结果0b1000110000。 35(0x23),没有分数。您虚拟小数点右边的第一位是2 ^ -1或1/2,下一位是2 ^ -2或1 / 4th等。



这是浮点的工作原理,但它基本上是一个科学记数法,大多数数字的肉在小数位的右边。就像中学或高中的科学记数法,你必须遵循这些规则,准备你的数字前后简单的数学运算。指数必须匹配之前,你可以添加例如,乘法他们不,但你添加指数以及乘以数字部分...


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:

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

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

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.

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.

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.

Thanks in advance!

解决方案

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

if I have these binary numbers I am multiplying

  abcd
* 1011
=======

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

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

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

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

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

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.

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天全站免登陆