C中的无符号Int乘法

时间:2015-02-17 23:47:05

标签: c int multiplication unsigned

所以我试图在C中实现这个算法,以便将32位unsigned int相乘,以便更好地理解它:

Step 1:  Test multiplier-0

Step 2:  if 1, add multiplicand to left half of product
        and place the result in the left half of 
        the product register


Step 3:  shift multiplier right 1 bit

Step 4:  shift product register right 1 bit

我没有得到的是如何实施第2步。它表示在产品的左半部分添加被乘数并存储在产品寄存器的左半部分。我很困惑如何只添加到产品的左半部分。我该怎么做?

编辑: 这是我带来的东西,但它没有给我正确的答案,我不知道出了什么问题。请帮忙!

long unsigned UnsignedMult(unsigned multiplicand, unsigned multiplier){

    unsigned int temp32a, temp32b;
    unsigned long temp64;
    unsigned long product;

    int i;

    product = multiplier;
    temp32b = multiplicand;


    for(i=0; i < 32; i++){
        if((product & 1)==1){ //add
           temp64 = product;
           temp64 = temp64 >> 32;
           temp32a = temp64;
           product = BinaryAdd(temp32a, temp32b); 
        }

        product = product >>= 1;

    }
    return product;
}

int BinaryAdd(int in1, int in2){

    int sum, carry;
    sum = in1 ^ in2; // x XOR y
    carry = in1 & in2; // x AND y carry in
    int i;    
    for (i = 0; i < 32; i++) {
        carry = carry << 1; 
        in1 = sum; 
        in2 = carry; 
        sum = in1 ^ in2; //calculate sum
        carry = in1 & in2; //find carry out
    }
    return sum;
}

1 个答案:

答案 0 :(得分:0)

产品寄存器的长度必须为64位,以允许两个32位整数相乘。希望您的编译器中有uint64_t可用来表示它(stdint.h)。

要进行添加,可以将被乘数放入64位整数,将其向左移位32位,然后将其添加到64位乘积寄存器中。

类似的东西:

uint64_t tmpMulti;
uint64_t productRegister = 0;
uint32_t multiplicand = 123;

tmpMulti = multiplicand;
tmpMulti <<= 32;
productRegister += tmpMulti;

(对于任何语法错误道歉,我很长时间没有编写C代码)

出于兴趣,我自己去实施它。这似乎有效:

#include <stdio.h>
#include <stdint.h>

void main(int argc, char* argv[])
{
    uint32_t multiplier = 17;
    uint32_t multiplicand = 12;

    uint64_t productRegister = multiplier;

    for (int n = 0; n < 32; n++) {
        if (productRegister & 1 == 1) {
            productRegister += ((uint64_t)multiplicand) << 32;
        }
        productRegister >>= 1;
    }

    printf("Result: %d\n", productRegister);
}

以下代码不使用<stdint.h>,并使用两个32位整数来表示64位产品寄存器。它不会尝试处理溢出,并假设答案适合32位。

#include <stdio.h>

void main(int argc, char* argv[])
{
    unsigned int multiplier = 17;
    unsigned int multiplicand = 12;

    unsigned int productRegisterLower = multiplier;
    unsigned int productRegisterUpper = 0;

    for (int n = 0; n < 32; n++) {
        if (productRegisterLower & 1 == 1) {
            productRegisterUpper += multiplicand;
        }
        productRegisterLower >>= 1;
        productRegisterLower |= productRegisterUpper << 31;
        productRegisterUpper >>= 1;
    }

    printf("Result: %d\n", productRegisterLower);
}

为了处理产品寄存器的右移,它将上半部分的最低有效位移动到下半部分的最高有效位。要做到这一点,它:

  • 将下半部分向右移1位。
  • 获取上半部分的副本并将其左移31位,以便最低有效位现在位于左侧,其余值为零。
  • 将其与下半部分进行或运算,将移位的位复制过来。
  • 将上半部分向右移1位。