C语言 没有算术运算符和循环的二进制乘法

jhdbpxl9  于 2023-11-16  发布在  其他
关注(0)|答案(3)|浏览(102)

我必须完成以下任务:
在不使用+-*/和位运算的情况下实现两个两位二进制数的写乘法。逻辑运算符&&||!只能应用于逻辑表达式,而不能应用于数字本身。这里不允许使用数组和循环。同样,在此不允许区分所有16种情况的解决方案。
代码的结构应便于扩展到具有更多位数的数字。
这两个数字是从控制台或通过文件重定向逐位输入的(正好是四位数)。对于个位数,还必须输入前导零。
要做到这一点,使用两个函数add(),它将两个不带进位的二进制数字相加(即返回0或1),以及carry(),它确定两个二进制数字相加时的进位。可以使用其他函数。
输出应该是这样的,两个因素是彼此相邻,没有前导零,然后一个等号跟随和产品没有前导零。
我的方法是Booth的二进制数乘法算法。然而,我不知道如何在没有循环的情况下实现它。
我有正确的算法吗?
上述算法的代码示例:

#include <stdio.h>

// Function to display a binary number
void displayBinary(int n) {
    if (n == 0) {
        printf("0");
        return;
    }

    int binary[32];
    int i = 0;

    while (n > 0) {
        binary[i] = n % 2;
        n /= 2;
        i++;
    }

    for (i--; i >= 0; i--) {
        printf("%d", binary[i]);
    }
}

// Function to perform Booth multiplication
int boothMultiplication(int multiplicand, int multiplier) {
    int m = multiplicand;
    int q = multiplier;
    int ac = 0; // Accumulator
    int q0 = 0; // Least significant bit of q
    int q1 = 0; // Next least significant bit of q

    int n = sizeof(int) * 8; // Number of bits in an integer 

    printf("Step\t\tA\t\tQ\t\tQ(-1)\tQ(0)\tOperation\n");

    for (int step = 1; step <= n; step++) {
        int q0_q1 = (q0 << 1) | q1;
        int operation = 0;

        if ((q0_q1 & 0b11) == 0b01) {
            ac += m;
            operation = 1;
        } else if ((q0_q1 & 0b11) == 0b10) {
            ac -= m;
            operation = -1;
        }

        if (q & 1) {
            q1 = q0;
        }
        q0 = q & 1;
        q >>= 1;

        printf("%d\t\t\t", step);
        displayBinary(ac);
        printf("\t");
        displayBinary(q);
        printf("\t");
        displayBinary(q1);
        printf("\t");
        displayBinary(q0);
        printf("\t");

        if (operation == 1) {
            printf("Addition (+%d)\n", m);
        } else if (operation == -1) {
            printf("Subtraction (-%d)\n", m);
        } else {
            printf("No Operation\n");
        }
    }

    return ac;
}

int main() {
    int multiplicand, multiplier;
    
    printf("Enter the multiplicand: ");
    scanf("%d", &multiplicand);
    
    printf("Enter the multiplier: ");
    scanf("%d", &multiplier);

    int product = boothMultiplication(multiplicand, multiplier);

    printf("\nResult: %d * %d = %d\n", multiplicand, multiplier, product);

    return 0;
}

字符串
The original task in German

yacmzcpb

yacmzcpb1#

假设您有以下位:abcd。这些位只能是0或1。
您正在尝试乘以ab * cd以产生4位值wxyz

ab * cd  ==  wzyz (decimal)
---------------------------
00 * 00  ==  0000 (0)
00 * 01  ==  0000 (0)
00 * 10  ==  0000 (0)
00 * 11  ==  0000 (0)
01 * 00  ==  0000 (0)
01 * 01  ==  0001 (1)
01 * 10  ==  0010 (2)
01 * 11  ==  0011 (3)
10 * 00  ==  0000 (0)
10 * 01  ==  0010 (2)
10 * 10  ==  0100 (4)
10 * 11  ==  0110 (6)
11 * 00  ==  0000 (0)
11 * 01  ==  0011 (3)
11 * 10  ==  0110 (6)
11 * 11  ==  1001 (9)

字符串
如果你把所有这些都放到Karnaugh map中,你将推导出以下用于计算w,x,y和z的布尔逻辑:

w = a & b & c & d;
    x = (a & c) & ~(a & b & c & d);
    y = ((a & d) | (b & c)) & ~(a & b & c & d);
    z = b & d;


或者简单地说:

w = a & b & c & d;
    x = (a & c) & ~w;
    y = ((a & d) | (b & c)) & ~w;
    z = b & d;


最后的结果可以这样计算:

int result = (w << 3) | (x << 2) | (y << 1) | z;


我不认为这满足了对更大位输入集的可扩展性的要求,也不认为这是用所讨论的加/进位方法实现的,但我把它作为一种可能性放在这里。

yqkkidmi

yqkkidmi2#

这应该满足要求。

#include <stdio.h>

int add(int b1, int b0) { return b1 != b0; }

int carry(int b1, int b0) { return b1==1 && b0==1; }

void print(int b3, int b2, int b1, int b0, char *s)
{
    int c = 0;
    if (b3==1 || c) printf("%i", b3), c = 1;
    if (b2==1 || c) printf("%i", b2), c = 1;
    if (b1==1 || c) printf("%i", b1), c = 1;
    printf("%i%s", b0, s), c = 1;
}

int main()
{
    int x1, x0, y1, y0, z3, z2, z1, z0, a1, a0;
    scanf("%i", &x1),   scanf("%i", &x0); 
    scanf("%i", &y1),   scanf("%i", &y0); 
    z1 = y0 ? x1 : 0,   z0 = y0 ? x0 : 0;
    a1 = y1 ? x1 : 0,   a0 = y1 ? x0 : 0;
    z2 = carry(z1, a0), z1 = add(z1, a0);
    z3 = carry(z2, a1), z2 = add(z2, a1);
    print( 0,  0, x1, x0, " * "),
    print( 0,  0, y1, y0, " = "),
    print(z3, z2, z1, z0, "\n");
}

字符串

s71maibg

s71maibg3#

只需做一个查找表。使用C23二进制表示法的示例:

unsigned int mul (unsigned int a, unsigned int b)
{
  // look-up table usage: [a][b] gives a * b
  static const unsigned int LUT [0b11 + 1][0b11 + 1] =
  {
    [0b00] = { [0b00] = 0, [0b01] = 0, [0b10] = 0, [0b11] = 0, },
    [0b01] = { [0b00] = 0, [0b01] = 1, [0b10] = 2, [0b11] = 3, },

    // and so on...
  };

  return LUT[a][b];
}

字符串

相关问题