КАК МНОЖЕСТВОВАТЬ 2 БОЛЬШИХ ЧИСЛА КАК СТРОН (с предыдущей фракцией, которая добавляет 2 строки)? c - PullRequest
0 голосов
/ 19 января 2020
verylong multiply_verylong(verylong vl1, verylong vl2)'verylong defines as typedef char* verylong'

{

size_t maxln, minln;
int carry=0, placeSaver=1, i, k ,sum=0,dif,newln,newln2,ln1,ln2;
verylong newNum , maxVl,minVl,tempvl,addvl;
ln1 = strlen(vl1); // 'length of first str'
ln2 = strlen(vl2);'length of second str'

if (ln1 >= ln2)
{


    maxln = ln1;
    minln = ln2;
    maxVl = (verylong)calloc(maxln + 1, sizeof(char));
    assert(maxVl);
    minVl = (verylong)calloc(minln + 1, sizeof(char));
    assert(minVl);
    strcpy(maxVl, vl1); 
    strcpy(minVl, vl2);
    dif = maxln - minln;
}


else 'stops debuging here'
{

    maxln = ln2;
    minln = ln1;
    maxVl = (verylong)calloc(maxln + 1, sizeof(char));
    assert(maxVl);
    minVl = (verylong)calloc(minln + 1, sizeof(char));
    assert(minVl);
    strcpy(maxVl, vl2);
    strcpy(minVl, vl1);
    dif = maxln - minln;
}

newln = 2 * maxln + 1; 'maximum length of new  required string'
newln2 = newln - 1; 'the index of the new string'

newNum = (verylong)calloc(newln,sizeof(char)); 
addvl = (verylong)calloc(newln, sizeof(char));
tempvl = (verylong)calloc(newln, sizeof(char));
for (i = minln - 1; i >= 0; i--) ' elementry school multiplication'
{


    for (k = maxln - 1; k >= 0; k--)
    {

        sum = ((minVl[i] - '0')*(maxVl[k] - '0')*placeSaver)+carry;
        if (sum >= 10)
            carry = sum / 10;
        if (k == 0)
            newNum[newln2] = '0' + sum;
        else
            newNum[newln2] = '0' + sum%10;
    newln2--;

    }


    placeSaver*=10; 
    addvl=add_verylong(newNum,tempvl);'sending the 2 strings to a previous function that adds 2 strings'
    strcpy(tempvl, addvl);


}


return addvl;

}

void main () {

char vl1[80], vl2[80];
printf("enter  large number\n"); 
gets(vl1);
printf("enter  large number\n");
gets(vl2);
verylong res = multiply_verylong(vl1, vl2);'saves the string  '
printf("%s", res);
free(res);

}

Я попытался умножить первое di git первого числа справа со всеми цифрами от второго числа, перемещающегося вперед ко второму di git первого числа, а затем умножить заставку на 10.

***

  • проблема в том, что код обычно ничего не выдает, а иногда просто неверный результат

***

1 Ответ

0 голосов
/ 20 января 2020

Ваш подход в основном правильный, но в реализации есть некоторые ошибки.

  • Вы выделяете место для addvl, но позже перезаписываете этот указатель возвращаемым значением add_verylong(). Это дает утечку памяти. Дальнейшие утечки памяти возникают, если не освободить tempvl, maxvl, minvl и newNum.
  • Вы забыли инициализировать tempvl числом "0".
  • Мы не можем сдвинуть промежуточное произведение, умножив каждый ди git на десятикратную placeSaver. Что мы можем сделать, это поместить 0 цифр справа от продукта newNum.
  • Не удалось правильно установить carry в каждом цикле l oop.
  • Вы пропустили что даже самые левые цифры могут дать carry.

В этом коде исправлены упомянутые ошибки:

    newNum = calloc(newln, sizeof(char)); 
    // do not allocate space for addvl - it would be lost
    tempvl = malloc(newln);
    strcpy(tempvl, "0");    // don't forget to initialize tempvl to "0"
    for (i = minln - 1; i >= 0; i--)    // elementry school multiplication
    {
        newln2 = newln - 1; // the index of the new string
        for (carry = 0, k = maxln - 1; k >= 0; k--) // clear carry before each loop
        {
            sum = (minVl[i] - '0')*(maxVl[k] - '0') + carry;
            carry = sum/10;
            newNum[--newln2] = '0' + sum%10;
        }
        if (carry) newNum[--newln2] = '0' + carry;
        addvl = add_verylong(newNum+newln2, tempvl);    // number starts at +newln2
        free(tempvl);                                   // free obsolete number
        tempvl = addvl;                                 // rather than strcpy()
        newNum[--newln-1] = '0';                        // instead of placeSaver*=10
    }
    free(maxVl), free(minVl), free(newNum);
    return addvl;

Это работает для примера multiply_verylong("23345", "34565"), но вы должны сделать дальнейшие тесты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...