目前共有4篇帖子。
【程序】補碼一位乘法——比較法
1樓 巨大八爪鱼 2016-12-10 10:41
#include <stdio.h>

//#define SHOW

#pragma warning(disable:4996)

void binout(char *s, char v)
{
    char i;
    printf("%s", s);
    for (i = 0; i < 8; i++)
    {
        if (v & 0x80)
            putchar('1');
        else
            putchar('0');
        if (i == 0)
            putchar('.');
        v <<= 1;
    }
}

short multiply(char x, char y)
{
    // 所有寄存器全部採用算術移位
    // 且都採用雙符號位
    char a = 0;
    char b2 = ~x + 1;
    char c = y;
    char cn = 0;
    char i;
    for (i = 1; i <= 8; i++) // 7位數值位需要8步操作
    {
        if ((c & 1) == 0 && cn == 1)
            a += x;
        else if ((c & 1) == 1 && cn == 0)
            a += b2;

        if (i != 8)
        {
            cn = c & 1; // c的最低位移入cn
            c >>= 1;

            // a的最低位移入c的最高位
            if (a & 1)
                c |= 0x80;
            else
                c &= 0x7f;
            a >>= 1;
        }

#ifdef SHOW
        binout("a=", a);
        binout(" c=", c);
        putchar('\n');
#endif
    }
    return (short)((a << 7) + ((c >> 1) & 0x7f));
}

void test(char a, char b)
{
    printf("%d * %d = %d\n", a, b, multiply(a, b));
}

void check(void)
{
    char a, b;
    short c;
    int cnt = 0;
    FILE *fp = fopen("result.txt", "w");
    if (fp == NULL)
        return;
    for (a = -64; a <= 63; a++)
    {
        for (b = -64; b <= 63; b++)
        {
            c = multiply((char)a, (char)b);
            if (a * b != c)
            {
                fprintf(fp, "Warning: %d * %d != %d\n", a, b, c);
                cnt++;
            }
            else
                fprintf(fp, "%d * %d = %d\n", a, b, c);
        }
    }
    fclose(fp);
    printf("Warning count: %d\n", cnt);
}

int main(void)
{
    check();
    test(-5, -3);
    test(-9, -16);
    test(-32, 1);
    test(-13, -11);
    return 0;
}
2樓 巨大八爪鱼 2016-12-10 10:41
【運行結果】
Warning count: 0
-5 * -3 = 15
-9 * -16 = 144
-32 * 1 = -32
-13 * -11 = 143
3樓 巨大八爪鱼 2016-12-10 10:46
注意:補碼一位乘法中A、B寄存器必須採用雙符號位。
因為11.1算術右移後是11.1,01.0算術右移後是00.1才對。
如果只有單符號位,那麼1.1右移要想得到1.1必須採用算術移位,而1.0右移想要得到0.1就必須採用邏輯移位,這樣就增加了硬件的複雜性。
不過,如果採用單符號位的同時規定A寄存器的移位方式為算術移位(signed char a),那麼x=-127~127時能得到正確結果,只不過x=-128時,得出的結果符號是錯誤的,例如-128 x 1算出來是128,-128 x -1算出來是-128等等,這時只需要對結果取反再加一就行了(也就是變補)。
4樓 巨大八爪鱼 2016-12-10 10:48
如果規定採用雙符號位,那麼x, y的取值範圍就是-64~63。

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2024 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。