簡體   English   中英

C中的無符號Int乘法

[英]Unsigned Int Multiplication in C

所以我試圖在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;
}

您的產品寄存器需要長度為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位。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM