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

void multiply_biginteger(int a, int b, int c) {
  int a1;
  int a0;
  int b1;
  int b0;
  int c2;
  int c1;
  int c0;
  int d2;
  int d1;
  int d0;
  int e3;
  int e2;
  int e1;
  int e0;

  int t;
  int carry;

  // build base 10K digits

  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;
  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(b, 3) * 1000;

  // multiply a and b

  t = a0 * b0;
  carry = t / BASE_10K;
  e0 = t % BASE_10K;

  t = a1 * b0 + carry;
  c2 = t / BASE_10K;
  c1 = t % BASE_10K;

  t = a0 * b1;
  carry = t / BASE_10K;
  d0 = t % BASE_10K;

  t = a1 * b1 + carry;
  d2 = t / BASE_10K;
  d1 = t % BASE_10K;

  t = c1 + d0;
  if (t >= BASE_10K) {
    t = t - BASE_10K;
    carry = 1;
  }
  else
    carry = 0;
  e1 = t;

  t = c2 + d1 + carry;
  if (t >= BASE_10K) {
    t = t - BASE_10K;
    carry = 1;
  }
  else
    carry = 0;
  e2 = t;

  e3 = d2 + carry;

  set_size(c, 15);

  set_digit(c, 0, e0 % 10); e0 = e0 / 10;
  set_digit(c, 1, e0 % 10); e0 = e0 / 10;
  set_digit(c, 2, e0 % 10); e0 = e0 / 10;
  set_digit(c, 3, e0);
  set_digit(c, 4, e1 % 10); e1 = e1 / 10;
  set_digit(c, 5, e1 % 10); e1 = e1 / 10;
  set_digit(c, 6, e1 % 10); e1 = e1 / 10;
  set_digit(c, 7, e1);
  set_digit(c, 8, e2 % 10); e2 = e2 / 10;
  set_digit(c, 9, e2 % 10); e2 = e2 / 10;
  set_digit(c, 10, e2 % 10); e2 = e2 / 10;
  set_digit(c, 11, e2);
  set_digit(c, 12, e3 % 10); e3 = e3 / 10;
  set_digit(c, 13, e3 % 10); e3 = e3 / 10;
  set_digit(c, 14, e3 % 10); e3 = e3 / 10;
  set_digit(c, 15, e3);

  zero_justify(c);

  return;
}
