C大数乘法

C big number multiplication

我试图为我的第一个测试编写一个大整数乘法,但如果 uint8_t 数字大于一个,则结果是错误的。我尝试了 2 天以找到解决方案并了解我做错了什么...

void main(void){
    uint8_t x[] = {0xFF};
    uint8_t y[] = {0xFF};
    uint8_t z[] = {0x00, 0x00};
    mul(x,1,y,1,z);
    printf("X*Y = Z: ");
    for(int i = 0; i < 2; i++)
        printf("%02X ",z[i]);
    printf("\n");
    //Output: X*Y = Z: FE 01 == FE01 CORRECT!

    uint8_t a[] = {0x0F, 0xFF};
    uint8_t b[] = {0x0F, 0xFF};
    uint8_t c[] = {0x00, 0x00, 0x00, 0x00};
    mul(a,2,b,2,c);

    printf("A*B = C: ");
    for(int i = 0; i < 4; i++)
        printf("%02X ",c[i]);
    printf("\n");
    //Output: A*B = C: 00 FE E0 01 != FFE001 WRONG?!

}
void mul(uint8_t *a, int a_n,uint8_t *b, int b_n,uint8_t *c){
    int i,j;
    uint16_t A;

    for(i = a_n-1; i >= 0; i--){
        A=0;
        for(j = b_n-1; j >= 0; j--){
            A += (uint16_t) a[i] * b[j]; 
            c[i+j+1] += A;
            A >>= 8;
        }
        c[i] = A;;
    }
}

至少有 1 个问题:

c[]

中溢出

c[i+j+1] += A; 可能溢出 c[]

   // A += (uint16_t) a[i] * b[j]; 
   // c[i+j+1] += A;
   // A >>= 8;
   A = (uint16_t) a[i] * b[j] + A + c[i+j+1];
   c[i+j+1] = A & 0xFFu;  // or A % 256u
   A >>= 8;

示例固定代码(有其他小的改进)

// Using re-ordered parameters for better static code analysis
// Use const
// Idiomatic to use size_t for array sizing/indexing
// Perhaps return c[] to allow for chained calls.
uint8_t *mul(size_t a_n, const uint8_t a[a_n], size_t b_n, const uint8_t b[b_n],
    uint8_t c[a_n + b_n]) {

  for (size_t i = a_n; i-- > 0;) {
    unsigned A = 0; // Let compiler use the natural unsigned rather than force uint16_t
    for (size_t j = b_n; j-- > 0;) {
      A += 1u * a[i] * b[j] + c[i + j + 1]; // 1u * vs. cast, let compiler optimize
      c[i + j + 1] = A & 0xFFu;
      A >>= 8;
    }
    c[i] = A;
  }

  return c;
}

尝试使用此代码

#include <string.h>
 
int main()
{
    int a[100],b[100];
    int ans[200]={0};
    int i,j,tmp;
    char s1[101],s2[101];
    scanf(" %s",s1);
    scanf(" %s",s2);
    int l1 = strlen(s1);
    int l2 = strlen(s2);
    for(i = l1-1,j=0;i>=0;i--,j++)
    {
        a[j] = s1[i]-'0';
    }
    for(i = l2-1,j=0;i>=0;i--,j++)
    {
        b[j] = s2[i]-'0';
    }
    for(i = 0;i < l2;i++)
    {
        for(j = 0;j < l1;j++)
        {
            ans[i+j] += b[i]*a[j];
        }
    }
    for(i = 0;i < l1+l2;i++)
    {
        tmp = ans[i]/10;
        ans[i] = ans[i]%10;
        ans[i+1] = ans[i+1] + tmp;
    }
    for(i = l1+l2; i>= 0;i--)
    {
        if(ans[i] > 0)
            break;
    }
    printf("Product : ");
    for(;i >= 0;i--)
    {
        printf("%d",ans[i]);
    }
    return 0;
}```