
// an alternative big integer multiply when the precision is 12
// it uses base 10K for speeding up the multiplication

void multiply_biginteger(int a, int b, int c) {
  int a2;
  int a1;
  int a0;
  int b2;
  int b1;
  int b0;
  int d5;
  int d4;
  int d3;
  int d2;
  int d1;
  int d0;

  int t;
  int carry;

  // build base 10K digits

  a2 =
    get_digit(a, 8) + get_digit(a, 9) * 10 +
    get_digit(a, 10) * 100 + get_digit(a, 11) * 1000;
  a1 =
    get_digit(a, 4) + get_digit(a, 5) * 10 +
    get_digit(a, 6) * 100 + get_digit(a, 7) * 1000;
  a0 =
    get_digit(a, 0) + get_digit(a, 1) * 10 +
    get_digit(a, 2) * 100 + get_digit(a, 3) * 1000;

  b2 =
    get_digit(b, 8) + get_digit(b, 9) * 10 +
    get_digit(b, 10) * 100 + get_digit(b, 11) * 1000;
  b1 =
    get_digit(b, 4) + get_digit(b, 5) * 10 +
    get_digit(b, 6) * 100 + get_digit(b, 7) * 1000;
  b0 =
    get_digit(b, 0) + get_digit(b, 1) * 10 +
    get_digit(b, 2) * 100 + get_digit(a, 3) * 1000;

  // multiply a and b

  t = a0 * b0;
  carry = t / BASE_10K;
  d0 = t % BASE_10K;
  t = a1 * b0 + carry;
  carry = t / BASE_10K;
  d1 = t % BASE_10K;
  t = a2 * b0 + carry;
  d3 = t / BASE_10K;
  d2 = t % BASE_10K;

  t = a0 * b1;
  carry = t / BASE_10K;
  d1 = d1 + t % BASE_10K;
  t = a1 * b1 + carry;
  carry = t / BASE_10K;
  d2 = d2 + t % BASE_10K;
  t = a2 * b1 + carry;
  d4 = t / BASE_10K;
  d3 = d3 + t % BASE_10K;

  t = a0 * b2;
  carry = t / BASE_10K;
  d2 = d2 + t % BASE_10K;
  t = a1 * b2 + carry;
  carry = t / BASE_10K;
  d3 = d3 + t % BASE_10K;
  t = a2 * b2 + carry;
  d5 = t / BASE_10K;
  d4 = d4 + t % BASE_10K;

  // carry digits

  carry = d1 / BASE_10K;
  d1 = d1 % BASE_10K;
  d2 = d2 + carry;
  carry = d2 / BASE_10K;
  d2 = d2 % BASE_10K;
  d3 = d3 + carry;
  carry = d3 / BASE_10K;
  d3 = d3 % BASE_10K;
  d4 = d4 + carry;
  carry = d4 / BASE_10K;
  d4 = d4 % BASE_10K;
  d5 = d5 + carry;

  set_size(c, 23);

  set_digit(c, 0, d0 % 10); d0 = d0 / 10;
  set_digit(c, 1, d0 % 10); d0 = d0 / 10;
  set_digit(c, 2, d0 % 10); d0 = d0 / 10;
  set_digit(c, 3, d0);
  set_digit(c, 4, d1 % 10); d1 = d1 / 10;
  set_digit(c, 5, d1 % 10); d1 = d1 / 10;
  set_digit(c, 6, d1 % 10); d1 = d1 / 10;
  set_digit(c, 7, d1);
  set_digit(c, 8, d2 % 10); d2 = d2 / 10;
  set_digit(c, 9, d2 % 10); d2 = d2 / 10;
  set_digit(c, 10, d2 % 10); d2 = d2 / 10;
  set_digit(c, 11, d2);
  set_digit(c, 12, d3 % 10); d3 = d3 / 10;
  set_digit(c, 13, d3 % 10); d3 = d3 / 10;
  set_digit(c, 14, d3 % 10); d3 = d3 / 10;
  set_digit(c, 15, d3);
  set_digit(c, 16, d4 % 10); d4 = d4 / 10;
  set_digit(c, 17, d4 % 10); d4 = d4 / 10;
  set_digit(c, 18, d4 % 10); d4 = d4 / 10;
  set_digit(c, 19, d4);
  set_digit(c, 20, d5 % 10); d5 = d5 / 10;
  set_digit(c, 21, d5 % 10); d5 = d5 / 10;
  set_digit(c, 22, d5 % 10); d5 = d5 / 10;
  set_digit(c, 23, d5);

  zero_justify(c);

  return;
}
