There are several ways to store and perform calculations with arbitrary precision numbers.
I believe the simplest example is to store the digits that make up the number in a string and do the calculations "practically" the same way we do
the account manually, however, this simple form does not provide very good performance.
Here is a practical, commented, and very simple example in C
of how to make a sum with arbitrary numbers:
#include <stdio.h>
#include <string.h>
// Tamanho do buffer
#define TAMANHO_MAXIMO 100000
// Retorna o máximo de 2 números
#define MAX(x, y) ((x) > (y) ? (x) : (y))
int soma(const char *num1, const char *num2, char resultado[], int max)
{
int d1, d2, i1, i2, r, soma;
int vai_um = 0;
int res;
// Índices dos números. Começa a soma a partir da unidade
i1 = strlen(num1);
i2 = strlen(num2);
// Retorna o tamanho do resultado a ser impresso
res = max - (MAX(i1, i2) + 1);
// Índice do resultado
r = max - 2;
d1 = d2 = soma = 0;
// Efetua a soma dígito a dígito
for (;;) {
// Se terminou finaliza o looping
if (i1 <= 0 && i2 <= 0)
break;
// Obtém os dois dígitos
d1 = i1-- <= 0 ? 0 : num1[i1] - 48;
d2 = i2-- <= 0 ? 0 : num2[i2] - 48;
// Soma os dígitos e o "vai um" se houver
soma = d1 + d2 + vai_um;
// Se a soma for maior que o dígito nove, "guarda" o "vai um"
if (soma > 9) {
vai_um = 1;
soma = soma - 10;
} else {
// se for menor que 9, o "vai um" é zero
vai_um = 0;
}
// Armazena dígito calculado
resultado[r--] = soma + 48;
};
// retorna o tamanho a ser impresso
return res;
}
int main()
{
// Números
char *n1 = "77843828938721973129372914798658749876459670949872346284631267542726289473294723948102389208120398347289347239472912345673414723947328947329472394810238920812039834728934723947298309563680458650468804968450685604586065486450684508654068059482309128301238019238120334332984732947492384772394723947329473294793248012983012318";
char *n2 = "289473294723948102389208120398347289347239472912345673414723947328262894732947239481023892081203983472893947329472394810238920812039834728934723947298309563680458650468804968450685604586065486450684508654068059482309128301238019238120334332984732947492384772394723947329473294793248012983012318";
// Resultado
char resultado[TAMANHO_MAXIMO];
// Tamanho do resulltado
size_t r;
// Preenche o resultado com 0
memset(resultado, 0, TAMANHO_MAXIMO);
// Coloca NULL no final da string
resultado[TAMANHO_MAXIMO - 1] = NULL;
printf("SOMA=%s\n + %s\n = \n\n", n1, n2);
// Chama a função soma e informa o tamanho máximo do buffer
r = soma(n1, n2, &resultado[0], TAMANHO_MAXIMO);
printf("%s\n", &resultado[r]);
getchar();
return 0;
}
After execution, the output is:
SOMA=778438289387219731293729147986587498764596709498723462846312675427262894732
94723948102389208120398347289347239472912345673414723947328947329472394810238920
81203983472893472394729830956368045865046880496845068560458606548645068450865406
80594823091283012380192381203343329847329474923847723947239473294732947932480129
83012318
+ 28947329472394810238920812039834728934723947291234567341472394732826289473294
72394810238920812039834728939473294723948102389208120398347289347239472983095636
80458650468804968450685604586065486450684508654068059482309128301238019238120334
332984732947492384772394723947329473294793248012983012318
=
77843828938721973129372914798948223171183619052261554405029614832073528946207069
62151711315544866124202229447895393623775461870742022289465894478962047784162407
96694578694478945966191273609173009376099369013712091721309729013690173081361189
64618256602476038476240668665969465894984769544789447894658946589586496025966024
636
In the example above, the buffer size is limited to TAMANHO_MAXIMO
however, in a real library, it can be dynamically allocated.
The other operations (subtraction, multiplication, division) are done in a similar way.
There are several techniques to optimize this type of operation, for example:
-
change the base of the number to a larger base (eg base 16, 64 or 256), because each digit occupies a smaller memory space
-
save the "go one" operation on a vector and apply it in just one loop at the end of the operation (used mainly in multiplication)
For more information on operations with arbitrary numbers and optimization:
The Art of Computer Programming - Vol 2
Numerical Recipes Home Page