Длинное умножение

Во входном файле задано два целых положительных числа, одно в первой строке, второе — во второй строке. Нужно вычислить произведение этих двух чисел и вывести его в выходной файл. Количество десятичных цифр в каждом входном числе может достигать 1 000. Поэтому требуется реализовать умножение двух длинных чисел “столбиком”. Моя программа работает правильно, но система тестирования не хочет ее принимать. Подскажите, почему, и как это можно исправить?

 #include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
 
#define BASE 1000000000u
#define WIDTH 9
 
typedef uint32_t Digit;
typedef uint64_t Digit2;
 
#define SCN_DIGIT SCNu32
#define PRI_DIGIT PRIu32
 
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
 
Digit *multiply(Digit p[], size_t n_p,
                const Digit a[], size_t n_a,
                const Digit b[], size_t n_b)
{
  for (; n_a > 0 && a[n_a - 1] == 0; --n_a);
  for (; n_b > 0 && b[n_b - 1] == 0; --n_b);
 
  if (n_a + n_b > n_p)
    return NULL;
 
  memset(p, 0, n_p * sizeof *p);
 
  for (size_t i_b = 0; i_b < n_b; ++i_b)
  {
    Digit carry = 0;
 
    for (size_t i_a = 0; i_a < n_a; ++i_a)
    {
      Digit2 digit = p[i_a + i_b] + (Digit2) a[i_a] * b[i_b] + carry;
      p[i_a + i_b] = digit % BASE;
      carry = digit / BASE;
    }
 
    p[n_a + i_b] += carry;
  }
 
  return p;
}
 
Digit *from_string(Digit a[], size_t n_a, const char *str)
{
  size_t i_a = 0;
  const char *pstr = str + strlen(str);
 
  char format[16];
  sprintf(format, "%%%d" SCN_DIGIT, WIDTH);
 
  for(; pstr - str > WIDTH && i_a < n_a; ++i_a)
    sscanf(pstr -= WIDTH, format, &a[i_a]);
 
  if (i_a == n_a)
    return NULL;
 
  sprintf(format, "%%%td" SCN_DIGIT, pstr - str);
  sscanf(str, format, &a[i_a]);
 
  ++i_a;
  memset(a + i_a, 0, (n_a - i_a) * sizeof *a);
 
  return a;
}
 
char *to_string(char *str, size_t n_str, Digit a[], size_t n_a)
{
  for (; n_a > 0 && a[n_a - 1] == 0; --n_a);
  size_t i_a = n_a - 1;
 
  char *pstr = str;
 
  char format[16] = "%" PRI_DIGIT;
  int n_chars = snprintf(NULL, 0, format, a[i_a]);
  if (n_chars + 1 > n_str)
    return NULL;
 
  sprintf(pstr, format, a[i_a]);
  pstr += n_chars;
  n_str -= n_chars;
 
  sprintf(format, "%%0%d" PRI_DIGIT, WIDTH);
 
  while (i_a-- > 0)
  {
    if (WIDTH + 1 > n_str)
      return NULL;
 
    sprintf(pstr, format, a[i_a]);
    pstr += WIDTH;
    n_str -= WIDTH;
  } 
 
  return str;
}
 
int main(void)
{
  char buffer[1024];
 
  scanf("%s", buffer);
  Digit a[10];
  from_string(a, ARRAY_SIZE(a), buffer);
 
  scanf("%s", buffer);
  Digit b[10];
  from_string(b, ARRAY_SIZE(b), buffer);
 
  Digit p[ARRAY_SIZE(a) + ARRAY_SIZE(b)];
  multiply(p, ARRAY_SIZE(p), a, ARRAY_SIZE(a), b, ARRAY_SIZE(b));
 
  to_string(buffer, ARRAY_SIZE(buffer), p, ARRAY_SIZE(p));
  printf("%s\n", buffer);
}

Ответы (0 шт):