0

我正在尝试为存储在两个数组中的 8 位二进制数实现长手乘法方法BeforeDecimal1 and BeforeDecimal2。问题是我总是得到错误的结果。我试图找出问题,但无法做到。这是代码:

这是一个比前一个更精致的代码。它给了我结果,但结果不正确。

int i=0,进位=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++;
}

问候

4

4 回答 4

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

如果要处理有符号数,通常最容易单独计算结果的符号,并对绝对值进行乘法运算。

于 2012-12-02T07:40:40.447 回答
0

您在以下代码行中遇到问题

if(reverse==0)
{
    totalReverse=totalReverse-1;
    reverse=totalReverse;
}

在内部 for 循环(基于索引 j)的一些迭代之后, reverse 的值应该变为负数,当 reverse 小于 3 时,应该抛出异常。

您是否在没有异常处理的情况下运行此代码?

于 2012-12-02T05:29:48.710 回答
0

对我来说,这闻起来像shift 和 add。是否要求您只能使用模拟逻辑门的操作?

对于您的全加器,您有 3 个输入 s(s[j])、b(BeforeDecimal1[j])、c(carry) 和两个输出 ns(new s[j])、nc (new carry) 表格看起来像这

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,我建议使用临时结果变量(进位和 s 在下一个 if 子句中仍然有效)

当您分析表格时,您也可以这样做(伪布尔符号)

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
}
// [...]

这是您的问题序列乘法的一个很好的模拟

于 2012-12-02T12:11:43.290 回答
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

于 2012-12-03T05:04:04.127 回答