Vediamo un problema pratico, spesso di difficile gestione ma potenzialmente molto utile. Come gestire un numero grande a piacere (intero oppure cifre decimali, che sia). La soluzione, in breve, è la seguente: si lavora con le stringhe. Dal punto di vista operativo non è così semplice, poiché va implementata una funzione ad-hoc per il caso specifico, l'operazione che vogliamo fare. In questo caso di esempio, vediamo un codice in linguaggio C, per sommare le cifre (non è banale poiché va tenuto in considerazione il famoso "riporto" e anche la dimensione totale della stringa che potrebbe variare a seconda dei numeri coinvolti nell'operazione).
Questa procedura diventa necessaria quanto abbiamo a che fare con numeri enormi o vogliamo un numero enorme di cifre decimali come accuratezza. Ad esempio il double è "limitato" a 64bit, 52bit di mantissa (ovvero per rappresentare le cifre decimali) e 53*log(2) = 16 cifre decimali.
Pensiamo all'esempio Algoritmi per calcolo pi greco a confronto: un caso come la Formula BBP, con elevata accuratezza, porta in breve tempo alla convergenza, vale a dire che, con un metodo "tradizionale" (ad esempio una variabile double) in poco tempo superiamo le cifre decimali a nostra disposizione. Dunque per risolvere tale limite, occorre un codice più complesso, gestione tramite stringhe.
Vediamo tutto il codice di un programma di esempio, che somma quindi due numeri (come detto, grandi a piacere):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Funzione per sommare due numeri decimali rappresentati come stringhe
char *sommaDecimali(const char *num1, const char *num2){
int len1 = strlen(num1);
int len2 = strlen(num2);
int maxLen = (len1>len2) ? len1:len2;
int carry = 0;
char *result = (char*)malloc(maxLen+2); // +1 per il possibile riporto e +1 per il terminatore NULL
int i,j,k;
for (i=len1-1,j=len2-1,k=0;i>=0 || j>=0 || carry>0; i--,j--,k++) {
int digit1 = (i>=0) ? (num1[i]-'0'):0;
int digit2 = (j>=0) ? (num2[j]-'0'):0;
int sum = digit1+digit2+carry;
carry = sum/10;
result[k] = (sum%10)+'0';
}
result[k] = '\0';
// Inverti la stringa risultante
for (int start=0,end=k-1; start<end; start++,end--) {
char temp = result[start];
result[start] = result[end];
result[end] = temp;
}
return result;
}
int main() {
const char *numero1 = "123456789123456789123456789123456789";
const char *numero2 = "987654321987654321987654321987654321";
char *somma = sommaDecimali(numero1, numero2);
printf("Somma: %s\n", somma);
free(somma);
return 0;
}
In particolare, questo programma di esempio fa questa somma:
- numero1: 123456789123456789123456789123456789
- numero2: 987654321987654321987654321987654321
- risultato: 1111111111111111111111111111111111110
Come detto, la strada di gestire operazioni (quindi la rappresentazione delle cifre) tramite le stringhe, è ovviamente ben più complessa da implementare rispetto ad una banale operazione aritmetica, anche un po' più lenta per le varie operazioni, ma fondamentale oltre un certo livello di accuratezza o grandezza del numero (quantità di cifre totali) da rappresentare. Spero che questo esempio sia utile! 🙂