Home > Software design >  C big number multiplication
C big number multiplication

Time:10-22

Im trying to write an big integer multiplication for my first test its working but if the uint8_t number is more than one than the result is wrong. I tried it 2 days to find a solution and to understand what Im doing wrong...

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("X ",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("X ",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;;
    }
}

CodePudding user response:

At least 1 problem:

Overflow in c[]

c[i j 1] = A; may overflow c[]. @Barmar

   // 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;

Sample fixed code (with other minor improvements)

// 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;
}
  • Related