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" in the same way we do
the account manually, however, this simple form does not offer a very good performance.
Follow a practical example, commented and very simple in C
how to make a summing up 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
Ne example above, buffer size is limited to constant 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 (ex: base 16, 64 or 256), as each digit occupies a smaller memory space
save the "go one" operation on a vector and apply it in just one looping at the end of the operation (mainly used in multiplication)
For more information on arbitrary numbers and optimization operations (in English):
The Art of Computer Programming - Vol 2
Numerical Recipes Home Page
Friends, I just want to suggest to add the article, one of the best I have read about this problem: LINK: https://www.vivaolinux.com.br/artigo/Programacao-com-integers
– weltonvaz
The size of the numbers used has nothing to do with the "power" of the computer. Simulation calculations on super computers are usually done with 64bit (double) floats - and nothing prevents even a netbook from having programs that use arbitrary precision numbers in any program, as can be seen in the answers below. The point is that in fact, the hardware in the Cpus is optimized to perform operations with a 32 or 64 bit float - above that (in general) the account has to be made in Software.
– jsbueno