С++ Написать алгоритм поразрядных операций с длинными целыми числами, представленными строками символов
Помогите, пожалуйста, сдетектить и исправить ошибки в коде. Я написал код для операций с длинными целыми числами(сложение, вычитание, умножение), и запутался в алгоритме работы. Буду сильно благодарен)
По заданию я ввожу 2 длинных целых неотрицательных числа a1 и a2, прога должна вывести результаты операций над ними. Цифры храню в динамических массивах char malloc, который как строки символов. Операции выполняются через функцию string_operations().
Поразрядные операции — это значит например, что каждый символов char первого числа складывается с char'ом второго числа, и они должны стоять на одинаковых позициях в числах. Если результат их сложения s > 9, то десятичный разряд числа запоминается флагом переноса, переносится и складывается со следующим разрядом.
Функция усложняется проверкой чисел на одинаковое кол-во символов, чтобы они правильно сладывались/вычитались.
То есть, если ввели a1 = 12000; a2 = 1100 то после проверки числа внутри функции приводятся к такому виду a1 = 12000; a2_same = 01100 . У обоих кол-во символов теперь 5. Строку с недостаточным кол-вом символов, переношу в an_same
Сейчас у кода такие проблемы:
Дебагер жалуется на моменте с проверкой чисел на одинаковое кол-во символов. Что-то я неправильно делаю с памятью и стеком. Решено, см. комментарии к вопросу

Если убрать проверку чисел на одинаковое кол-во символов, то дальше видно, что алгоритм некорректно работает с вычитанием и умножением чисел. А именно из меньшего не вычитается большее, если результат больше 10, то не работает перенос десятичного разряда на следующую позицию. Я не понимаю, какие ошибки в алгоритме
Тут приложу разные тесты, чтобы было легче понять, где ошибка

- Наверное, неправильно сразу создавать массивы с размером N. Правильнее будет создать пустой массив и по ходу алгоритма выделять память realloc. Но не понимаю, в каком именно месте алгоритма ставить realloc, т.к. переносы и так не работают.
Вот сам код (не обращайте внимание, что C мешается с C++, это не правильно, я это исправлю, но пока мне важна работающая программа и алгоритм):
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;
#define N 81
char* sum = (char*)malloc(sizeof(char) * N * N);
int string_operations(char* a1, char* a2, char action, char* sum)
{
int carry, i = 0, v1, v2, s;
char a1_same[N]{};
char a2_same[N]{};
sum[0] = 0;
size_t a1_length = strlen(a1); // кол-во символов a1
size_t a2_length = strlen(a2); // кол-во символов a2
// блок кода ниже для обработки цифр разной длины, чтобы они складывались правильно, к числу с меньшей длиной прибавляю слева нули 0, до длины большего числа
//----------------------------------------------------------------------------------------
if (a1_length > a2_length)
{
size_t temp = a1_length - a2_length; // кол-во недостающих символов, чтобы уравнить a2 с a1
for (i = 0; i < temp; i++) // в a2_same добавляем кол-во нулей, до уравнения длины a2 с a1
{
a2_same[i] = '0';
}
strcat_s(a2_same, temp, a2); // к концу a2_same добавляем копию a2
}
else if (a2_length > a1_length)
{
size_t temp = a2_length - a1_length; // кол-во недостающих символов, чтобы уравнить a1 с a2
for (i = 0; i < temp; i++) // в a1_same добавляем кол-во нулей, до уравнения длины a2 с a1
{
a1_same[i] = '0';
}
strcat_s(a1_same, N, a1); // к концу a1_same добавляем копию a1
}
//----------------------------------------------------------------------------------------
// поразрядно работаем с числами
carry = 0; // флаг переноса
for (i = a1_length - 1; i >= 0; i--)
{
if (a1_length > a2_length)
{
v1 = (int)(a1[i] - '0');
v2 = (int)(a2_same[i] - '0');
}
else if (a2_length > a1_length)
{
v1 = (int)(a1_same[i] - '0');
v2 = (int)(a2[i] - '0');
}
else
{
v1 = (int)(a1[i] - '0');
v2 = (int)(a2[i] - '0');
}
if ((v1 < 0) || (v1 > 9) || (v2 < 0) || (v2 > 9)) cout << "Введена не цифра \n";
if (action == '+')
{
s = v1 + v2 + carry;
if (s <= 9)
carry = 0;
else
{
s = s - 10;
carry = 1;
}
}
else if(action == '-')
{
if (v1 >= v2)
{
s = v1 - v2 - carry;
if (s >= 0)
carry = 0;
else
{
s = s + 10;
carry = 1;
}
}
else
{
s = v2 - v1 - carry;
s = -fabs(s); // знак меняется на минус
carry = 0;
}
}
else // умножение
{
s = v1 * v2;
if (s > 9)
{
int m = (v1 * v2) / 10; // десятичная часть числа
int f = (v1 * v2) - (m * 10); // единичная часть числа
s = m;
sum[i + 1] = m; // десятичная часть числа переносится в следующий разряд
sum[i] = f; // единичная часть числа остается на своем разряде
}
}
sum[i] = (char)(s + '0'); // добавление результата вычисления в массив sum
}
sum[a1_length] = 0;
return 0;
}
int main()
{
setlocale(LC_ALL, "Russian");
int result;
char *a1 = (char*)malloc(sizeof(char) * N);
char *a2 = (char*)malloc(sizeof(char) * N);
cout << "Введите первое длинное число \n";
cin >> a1;
cout << "Введите второе длинное число \n";
cin >> a2;
// сложение
result = string_operations(a1, a2, '+', sum);
printf("%s+%s=%s r=%d\n", a1, a2, sum, result);
// вычитание
result = string_operations(a1, a2, '-', sum);
printf("%s-%s=%s r=%d\n", a1, a2, sum, result);
// умножение
result = string_operations(a1, a2, '*', sum);
printf("%s*%s=%s r=%d\n", a1, a2, sum, result);
//очистка памяти
free(a1);
a1 = NULL;
free(a2);
a2 = NULL;
free(sum);
sum = NULL;
return 0;
}
Спасибо, что помогаете начинающим! ❤