Long Multiply C

时间:2014-10-07 19:22:40

标签: c multiplication arbitrary-precision

我正在尝试在C中实现long multiply方法(小学校法)。我需要在base 2 ^ 32中编写我的程序。我不知道怎么开始。我有我想在这里使用的算法:

for (i = 0; i < n; i++) {
   carry = 0;
   for (j = 0; j < n; j++) {
      product = a[i] * b[j] + result[i + j] + carry;
      result[i + j] = p % base;
      carry = floor(product / base);
   }
   result[i + n] = carry;
}

任何提示都表示赞赏。我只是想出一个好主意。

3 个答案:

答案 0 :(得分:3)

主要的“技巧”是找到一种方法来处理多个两个32位数字并得到一个64位数字或两个32位数字,它们是高半部分和低半部分。高半部分是进位,低半部分是结果(模式2 ^ 32)。在x86机器上有一个汇编语言指令就是这样做的,但是要用直接的C / C ++来完成,你需要在乘法之前将被乘数转换为某些64位类型,然后使用移位和掩码来分离高位和两半。

答案 1 :(得分:2)

想象一下,我有两个带'数字'的数字:

b_2 b_1 b_0

a_1 a_0

将这些加在一起我们首先乘以所有'b'乘以a_0。然后我们将所有'b'乘以a_1并将结果向左移动一个位置(即32位),然后再将两个结果相加。

要乘以a_0,将a_0移动到64位变量,然后乘以b_0。底部32位是乘法结果c_0的底部32位。前32位是进位。

接下来将a_0乘以b_1(再次以64位)。取结果的底部32位并添加进位,这将使结果的下一个32位:'c_1'。前32位是下一个进位。重复此操作,直到您乘以b中的所有数字。最后一个进位是结果的前32位。

然后对a_1做同样的事情。获得乘法结果后,请记住在a_1乘法结束时添加额外的32位。然后将a_1和1_0相乘的结果加在一起。

答案 2 :(得分:2)

为了在base中使用数字加倍,您需要原生乘法并添加可处理base中两位数的指令。因此,如果base为2 32 ,则需要64位类型,以及32位类型。

这样,您最终得到的代码如下:

/* multiply two n-word numbers, giving a 2n-word result */
void multiply(uint32_t *result, uint32_t *a, uint32_t* b, int n) {
    int i, j;
    for (i = 0; i < 2*n; i++)
        result[i] = 0;
    for (i = 0; i < n; i++) {
        uint32_t carry = 0;
        for (j = 0; j < n; j++) {
            uint64_t product = (uint64_t)a[i] * b[j] + result[i + j] + carry;
            result[i + j] = product & 0xffffffff;
            carry = product >> 32; }
        result[i+n] = carry; }
}

基本上与您拥有相同的代码,使用强制转换来确保它使用正确的类型。