Newsgroup: it.comp.lang.c
Titolo: realizzare programma in c che faccia sottrazione tra due numeri naturali da 20 cifre

[c] realizzare programma che fa sottrazione tra 2 numeri naturali da 20
cifre
ciao a tutti
 per l'università devo realizzare un programma in c (non in c++ o
altro)
 premesso che le mie conoscenze sono molto limitate, il programma deve
fare la sottrazione tra due numeri naturali di 20 cifre. o meglio da un
numero di massimo 20 cifre ne va sottratto un altro qualsiasi
 ho già realizzato un semplice programma di sottrazione tra due
numeri, il problema e' che se inserisco numeri di oltre dieci cifre mi
sballa tutto quanto
 
 come posso fare per risolvere il problema?
 potete aiutarmi ?

 ha scritto nel messaggio
news:1153474421....@s13g2000cwa.googlegroups.com...

Un metodo semplice, per il caso più generale di
qualunque numero di cifre occorre allocazione
dinamica della memoria,  potrebbe essere quello
di rappresentare l'intero con un array di caratteri e poi lavorare
sulla rappresentazione "testuale" del numero stesso.
L'input/output avviene quindi come per le stringhe.
Es:
#define MAX_NUM_LEN 20
typedef struct {
        char rappresentazione[MAX_NUM_LEN+1+1]; /* potrebbero servire lo
'\0' e il segno */
} Numero;
Bisogna fare attenzione a rappresentare i negativi e lavorare bene in
complemento
a 2 o 1 o altro.
Le routine devi farle tu altrimenti non vale ...
Giorgio Silvestri

Giorgio Silvestri ha scritto:

ciao Giorgio grazie del tuo aiuto
non ho capito bene il discorso del lavorare in complemento..
puoi essere più chiaro a riguardo?
intanto grazie
oggi provo a buttare giù qualcosa e dopo lo posto così poi mi dici..
;)
grazie ancora
ciao

puoi essere più chiaro a riguardo?
Forse l'aiuto è fuorviante ma volevo solo dire che se dovessi
fare una scelta per rappresentare i numeri negativi
hai diverse possibilità:
Es: il numero -1 diventa, dentro rappresentazione[]:
1) In modo testo: rappresentazione[] = "-1"
2) Complemento alla base: rappresentazione[] = "99999999999999999999"
3) Complemento alla base-1: rappresentazione[] = "99999999999999999998"
4) altro...
dove con base intendo 10 e non 2 come nel precedente post.
Naturalmente devi fare anche delle opportune routine
di input/output dei  numeri.
Dipende come ti trovi meglio e quali operazioni in futuro
dovrai fare su tali rappresentazioni...
Giorgio Silvestri

 ha scritto nel messaggio
news:Ql7wg.48709$_J1.5...@twister2.libero.it...

Naturalmente l'idea dell'array di caratteri è appunto solo un'idea.
Un modo più serio ed efficiente è quello di rappresentare i numeri
con un array di int/long o altro e lavorare su di essi a pezzi.
Cioè prima sugli elementi LSB via via fino a quelli MSB
senza mai incorrere in overflow gestendo bene i riporti ecc.
Molti anni fa feci una libreria per gestire appunto numeri
in precisione illimitata, solo la memoria del PC era un limite ...
Gestendo la memoria in modo dinamico e trattando i numeri
appunto come array che evolvono mano a mano che il
numero cresce.
La complicazione sta nel fatto che come dicevo tutte le
operazioni intermedi vanno fatte in modo da non
superare mai il limite imposto dal tipo usato per
rappresentare il singolo digit, int o long che sia.
Spero di non aver complicato troppo. Prendi questo
solo come un'altra idea ...
Giorgio Silvestri

ciao grazie
 dunque ora come ora per fare il tutto sto facendo nel seguente modo:
 - 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)
 - 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
Infatti non capisco perché:
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 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
controllasse che:
 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?
 grazie mille

 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

ciao, grazie per le vostre risposte.. volevo ora chiedervi la
"correzione" del programma che ho battuto insieme ad un amico
il programma purtroppo non funziona e io devo consegnarlo domani
mattina.. per favore, è urgentissimo, qualcuno  potrebbe correggermi
gli errori ?
grazie mille
ciao
[code]
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TERM 100
int main(int argc, char *argv[])
{
	char num[21];
	char num2[21];
	printf("Inserisci il primo numero\n");
	scanf("%s",&num);
	printf("Inserisci il secondo numero\n");
	scanf("%s",&num2);
	//Inizio a copiare l'array char dentro un array int
	unsigned int num_i[20];
	unsigned int num_i2[20];
	int pos;
	char temp[2];
	temp[1]='\0';
	for (pos=0; pos<=20; pos++)
	{
		temp[0]=num[pos];
		num_i[pos]=atoi(temp);
		printf("%i\n",num_i[pos]);
	}
	temp[1]='\0';
	for (pos=0; pos<=20; pos++)
	{
		temp[0]=num2[pos];
                num_i2[pos]=atoi(temp);
                printf("%i\n",num_i2[pos]);
        }
	int numero[20],numero2[20];
	memset(numero,'0',sizeof(numero));
        memcpy(numero+20-strlen(num),num_i,strlen(num));
        memset(numero2,'0',sizeof(numero2));
        memcpy(numero2+20-strlen(num2),num_i2,strlen(num2));
	//Inizio la sottrazione
	int cicle,int result[20];
	for (cicle=20;cicle>=0;cicle--)
	{
			if( sizeof(numero2) > sizeof(numero) )
				printf("Errore! Perfavore inserire prima il numero maggiore!\n");
				exit 0;
			if( numero[cicle] > numero2[cicle])
				result[cicle] = numero[cicle] - numero2[cicle];
			if( numero[cicle] < numero2[cicle])
			{
				numero[cicle-1]--;
				numero[cicle] += 10;
				result[cicle] = numero[cicle] - numero2[cicle];
			}
			if( numero[cicle] < 0)
				printf("Errore!\n");
	printf("Il risultato della sottrazione è: %i",reult);
	return(0);
}
[/code]
 :muro:    :muro:

 printf("Il risultato della sottrazione è: %i",reult);
?????
Ci sono troppi errori.
Devi spedire un codice direttamente compilato e non
un ulteriore copia manuale dai file sorgenti.
Siamo lontani dalla soluzione.
Eppure se partivi dai miei frammenti di codice, sopratutto per
l'input, l'esercizio era praticamente finito ...
--
Giorgio Silvestri