Умножение большого числа - PullRequest
0 голосов
/ 20 апреля 2020

Я сделал код для умножения и добавления больших чисел, хранящихся в виде векторов, но слишком медленно. Я сгруппировал числа в группы по 18 цифр, и сложение происходит быстрее и правильнее, но умножение теперь не правильно. Прежде чем сгруппировать числа, я умножил каждое число di git на di git, а затем добавил их, и результат оказался верным. Но теперь, когда di git сгруппированы, я не уверен, почему результат не правильный.

#include "pch.h"
#include <stdio.h> 
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>

using namespace std;


void LongNumSet(long long int* L, unsigned N, long long int digit)
{
    for (int i = 0; i < N; i++)
    {
        L[i] = digit;
    }
}


void LongNumCopy(long long int *Vin, long long int *Vout, unsigned N)
{
    for (int i = 0; i < N; i++)
    {
        Vout[i] = Vin[i];
    }
}

void LongNumPrint(long long int *L, unsigned N, const char *Name)
{
    printf("%s:", Name);
    for (int i = N; i > 0; i--)
    {
        cout << L[i - 1];
    }
    printf("\n");
}

void LongNumInit(long long int *L, int N)
{
    for (int i = 0; i < N; i++)
    {
        long long int inputNum = 0;

        for (int j = 0; j < 18; j++) {
            int num = myRandom() % 10;  // digito decimal
            inputNum = inputNum * 10 + num; 
        }
        //cout << inputNum << endl;

        L[i] = inputNum;

    }
}

char LongNumConstMult(long long int* V, unsigned N, int digit)
{
    char CARRY = 0;
    for (int i = 0; i < N; i++)
    {

        long long int R = V[i] * digit + CARRY;

        //cout << V[i] << " " << digit << " " << R << "  " << CARRY << endl;

        CARRY = R / 10;
        R = R - CARRY * 10;
        V[i] = R;


    }
    return CARRY; // may be from 0 to 9
}

void LongNumAddition(long long int *Vin1, long long int *Vin2, long long int *Vout, unsigned N)
{
    char carry = 0;

    for (int i = 0; i < N; ++i) {
        Vout[i] = Vin1[i] + Vin2[i] + carry;

        //cout << Vin1[i] << " " << Vin2[i] << " " << carry << endl;

        carry = (Vout[i] > 9999999999999999999);

        if (carry) {
            Vout[i] -= 10;
        }
    }
}

void LongNumMultiply(long long int *Vin1, long long int *Vin2, long long int *VoutH, long long int *VoutL, unsigned N)
{

    // Create Temporal Long Integer with double size
    long long int *TEMP = (long long int*)malloc(2 * N * sizeof(long long int));
    long long int *RES = (long long int*)malloc(2 * N * sizeof(long long int));

    LongNumSet(RES, 2 * N, 0);    // Set RES to 0

    for (int i = 0; i < N; i++)
    {
        long long int num = Vin2[i];

        for (int j = 0; j < 18; j++) {

            LongNumSet(TEMP, 2 * N, 0);            // Set TEMP to 0
            LongNumCopy(Vin1, TEMP + i, N);         // Copy Vin1 -> TEMP, with offset i
            LongNumConstMult(TEMP, 2 * N, num % 10);  // TEMP * Vin2[i] -> TEMP
            LongNumAddition(TEMP, RES, RES, 2 * N); // TEMP + RES -> RES

            num /= 10;

        }
    }

    // Result goes to VoutH-VoutL
    LongNumCopy(RES, VoutL, N);  // Copy RES   -> VoutL
    LongNumCopy(RES + N, VoutH, N);  // Copy RES+N -> VoutH
}


// Driver program 
int main()
{
    int N = 60;
    N /= 17;
    long long int *V1 = (long long int*)malloc(N * sizeof(long long int));
    long long int *V2 = (long long int*)malloc(N * sizeof(long long int));
    long long int *V3 = (long long int*)malloc(N * sizeof(long long int));
    long long int *V4 = (long long int*)malloc(N * sizeof(long long int));

    LongNumInit(V1, N);
    LongNumInit(V2, N);
    LongNumInit(V3, N);

    LongNumAddition(V1, V2, V4, N);
    LongNumMultiply(V3, V4, V2, V1, N);

    return 0;
}
...