Post by Andre_Santarellciao grazie
- Leggo il primo numero da input (come stringa) e verifico che sia
lungo 20 caratteri;
- Leggo il secondo numero da input e verifico che sia lungo 20
caratteri o meno;
- Usando la funzione "atoi" dentro ad un for converto carattere per
carattere la stringa in interi, che metto in un array (lo fo per
entrambi i numeri)
Senza vedere il codice, che sarebbe
interessante investigare quando hai qualcosa pronto, ti posso
dire che le ottimizzazioni su questo genere di cose sono
praticamente infinite. Vediamo qualcosa.
Se il tuo array di interi è lungo come quello dell'input
allora atoi è totalmente inutile, e anche l'array di interi a questo
punto!
Puoi ottenere il valore intero corrispondente del digit
i-esimo e metterlo direttamente nell'array di input
nel modo seguente:
#define MAX_NUM_LEN 20
int i;
for (i=0; i<MAX_NUM_LEN; ++i) {
rappresentazione[i] -= '0';
}
E' chiaro cosa ho fatto ? Ora rappresentazione[i] è
un vero intero da 0 a 9.
Assumiamo input corretto.
Cioè tutte le cifre sono caratteri tra '0' e '9'.
Post by Andre_Santarell- Con una funzione costruita ad hoc eseguo la sottrazione tra i due
array, facendo attenzione ai riporti e alla lunghezza dei due array;
Il problema arriva in quest'ultimo punto
1) devo porre se la prima cifra è minore della secondaun risultato
uguale a zero
2) mettiamo che ad esempio si voglia fare 123 meno 4
sarebbe necessario che il programma legga i due numeri come 123 meno
004 e non come 123 meno 400
il problema infatti e' far partire ilprogramma a fare la sottrazione
dall'ultima cifra e non dalla prima.. te hai consigli per fare ciò?
viceversa avevamo pensato di fare leggere al programma 123 come
00000000000000000123
meno
00000000000000000003
ossia aggiungendo all'inizio del numero tanti zeri quanti sono le
cifre mancanti per arrivare a 20.
ma come fare questo?
Una volta che in una stringa di lunghezza n, n <= MAX_NUM_LEN
vuoi riempire con dei '0' a sinistra puoi fare così:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NUM_LEN 20
typedef struct {
char rappresentazione[MAX_NUM_LEN+1+1];
} Numero;
static void fill_with_0(Numero *x)
{
size_t n;
n = strlen(x->rappresentazione);
if (n < MAX_NUM_LEN) {
/* non memcpy !!! */
if (n) {
memmove(&x->rappresentazione[MAX_NUM_LEN -
n],x->rappresentazione,n);
}
memset(x->rappresentazione,'0',MAX_NUM_LEN - n);
x->rappresentazione[MAX_NUM_LEN] = '\0'; /* solo per stampare */
}
}
int main(void)
{
Numero numero;
sprintf(numero.rappresentazione,"9");
fill_with_0(&numero);
printf("%s\n",numero.rappresentazione);
return EXIT_SUCCESS;
}
Post by Andre_Santarelluna volta che si hanno i due numeri a 20 cifre complete si pensava di
fargli fare una sottrazione tra prima cifra da sinistra del primo
numero e prima cifra da sinistra del secondo numero. e che quindi
se la cifra del primo numero e' maggiore o uguale aquella del secondo
faccia la semplice sottrazione tra due numeri e la memorizzi
se invece la cifra del primo numero è minore di quella del secondo
consideri la prima cifra con l'aggiunta di 10, quindi faccia la normale
sottrazione e scali il risultato dell' operazione delle due cifre
precedenti di uno.
ci sono modi più rapidi?
Questo metodo è estremamante inefficiente.
Bisogna partire da LSB come ho detto in precedenza.
Ricalcando come si fa con carta e penna.
Considera quello che dovresti fare con la seguente
coppia di numeri:
10000000000000000000
meno
00000000000000000001
e partendo da sinistra!
Mentre partendo da LSB (destra) non devi avere memoria di più di
un riporto!
A dire la verità si potrebbe migliorare anche la versione da
sinistra. Comunque da destra è più facile, perlomeno più
consueto...
Se invece vuoi usare un ulteriore array di interi, in modo efficiente,
allora tale array ha dimensione molto minore
di MAX_NUM_LEN.
Nel nostro caso basterebbe grande 3 se usiamo i long.
In questo modo tutti i conti interni sono ancora più efficienti.
Questo problema nasce con dimensioni gigantesche dei numeri
stessi, quando l'I/O è limitato rispetto la mole di calcolo effettivo.
Nello specifico l'intero calcolo della differenza tra due
numeri diventerebbe:
#define LSIZE 3
long out_array[LSIZE];
long num1[LSIZE];
long num2[LSIZE];
/* ... */
out_array[2] = num1[2] - num2[2]; /* + gestione riporti ... */
out_array[1] = num1[1] - num2[1]; /* + gestione riporti ... */
out_array[0] = num1[0] - num2[0]; /* + gestione riporti ... */
in num1[0] metto il valore intero di rapp[8],...,rapp[0]
in num1[1] metto il valore intero di rapp[17],...,rap[9]
in num1[2] metto il valore intero di rapp[19],...,rap[18]
ecc.
Giorgio Silvestri