我正在尝试为存储在两个数组BeforeDecimal1 and BeforeDecimal2
中的8位二进制数实现Long Hand Multiplication方法。问题是我总是得到错误的结果。我试图找出问题,但无法做到。这是代码:
这是一个比前一个更精致的代码。它给了我结果,但结果不正确。
int i = 0,carry = 0;
while(true)
{
if(BeforeDecimal2[i]!=0)
for(int j=7;j>=0;j--)
{
if(s[j]==1 && BeforeDecimal1[j]==1 && carry==0)
{
cout<<"Inside first, j= "<<j<<endl;
carry=1;
s[j]=0;
}
else
if(s[j]==1 && BeforeDecimal1[j]==0 && carry==1)
{
cout<<"Inside second, j= "<<j<<endl;
carry=1;
s[j]=0;
}
else
if(s[j]==0 && BeforeDecimal1[j]==0 && carry==1)
{
cout<<"Inside third, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==0 && BeforeDecimal1[j]==0 && carry==0)
{
cout<<"Inside fourth, j= "<<j<<endl;
carry=0;
s[j]=0;
}
else
if(s[j]==0 && BeforeDecimal1[j]==1 && carry==0)
{
cout<<"Inside fifth, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==1 && BeforeDecimal1[j]==1 && carry==1)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=1;
s[j]=1;
}
else
if(s[j]==1 && BeforeDecimal1[j]==0 && carry==0)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==0 && BeforeDecimal1[j]==1 && carry==1)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=1;
s[j]=0;
}
}
for(int h=7;h>=0;h--)
{
if(h==0)
{
BeforeDecimal1[0]=0; // that is inserting zeros from the right
}
else
{
BeforeDecimal1[h]=BeforeDecimal1[h-1];
BeforeDecimal1[h-1]=0;
}
}
if(i==3)
break;
i++;
}
此致
答案 0 :(得分:2)
也许最简单的方法是备份并开始存储为8位二进制数的8位二进制数。就像我们进行十进制乘法时一样,我们从一些数字开始。我们将乘以这些个别数字的值,并将它们加在一起以得到最终结果。差异(或一个明显的差异)是这个,因为我们使用二进制,我们所有的数字代表2的幂,所以我们可以通过简单的位移输入得到每个中间结果。
由于它是二进制的,我们每个数字只有两种可能性:如果它是0,那么我们需要将另一个数字的0倍加上左移适当数量的位数。显然,无论什么时候0都是0,所以在这种情况下我们什么都不做。另一种可能性是我们有一个1,在这种情况下我们将另一个数字加1倍左移相应数量的位置。
例如,让我们考虑17 x 5或(二进制)10001 x 101之类的东西。
10001
101
------
10001
+ 1000100
--------
= 1010101
将其转换为更易识别的东西,我们得到0x55,或85 d 。
在代码中,该过程相当简短。从结果0开始。检查是否设置了一个操作数中的最低有效位。如果是,请将另一个操作数添加到结果中。将一个操作数向右移动一点,另一个向左移动一点,然后重复,直到你向右移动的操作数等于0:
unsigned short mul(unsigned char input1, unsigned char input2) {
unsigned short result = 0;
while (input2 != 0) {
if (input2 & 1)
result += input1;
input1 <<= 1;
input2 >>= 1;
}
return result;
}
如果你想处理带符号的数字,通常最容易单独计算结果的符号,并对绝对值进行乘法。
答案 1 :(得分:0)
您在以下代码行中遇到问题
if(reverse==0)
{
totalReverse=totalReverse-1;
reverse=totalReverse;
}
在内部for循环(基于索引j)的一些迭代之后,反向的值应该变为负值,而当反向的值小于3时,应该抛出异常。
您是否在没有异常处理的情况下运行此代码?
答案 2 :(得分:0)
为你的full adder你有3个输入s(s [j]),b(BeforeDecimal1 [j]),c(进位)和两个输出ns(new s [j]),nc(new携带) 表格看起来像这样
s b c ns nc
0 0 0 0 0 handled in v5 clause 4
0 0 1 1 0 handled in v5 clause 3
0 1 0 1 0 handled in v6 clause 5
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1 handled in v5 clause 2
1 1 0 0 1 handled in v5 clause 1
1 1 1 1 1
您的代码仅涵盖这8个条款中的4个(现在为5个)
避免丑陋的if-else-if rake我建议使用临时结果变量(在下一个if子句中,carry和s仍然有效)
当你分析表时你也可以做(伪布尔符号)
nc = s && b || s && c || b && c;
ns = s XOR b XOR c; // there is no XOR in C++: axb = a&&!b || !a&&b
算术符号
nc = (s + b + c) / 2;
ns = (s + b + c) % 2;
// [...]
for(int j=7;j>=0;j--)
{
// start changed code
const int sum = s[j] + BeforeDecimal1[j] + carry;
s[j]=sum % 2;
carry=sum / 2;
// end changed code
}
// [...]
这是一个很好的模拟您的问题Sequential Multiplication
答案 3 :(得分:0)
除非您的要求另有说明,否则您的问题或您目前的任何评论都不清楚,因此没有必要处理位数组。字节数组在空间和时间上都更有效。
你也不需要这种详尽的案例爆炸。唯一的特例是任一操作数为零,即a[i]|b[i] == 0
,
result[i] = carry;
carry = 0;
所有其他案件均可通过以下方式处理:
result[i] = a[i]*b[i]+carry;
carry = (result[i] >>> 8) & 1;
result[i] &= 0xff;
我在名称BeforeDecimal1
和BeforeDecimal2
中看不到多少意见。