所以我试图在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;
}
答案 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);
}
为了处理产品寄存器的右移,它将上半部分的最低有效位移动到下半部分的最高有效位。要做到这一点,它: