|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: May 2004
Messaggi: 2691
|
[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, ilprogramma 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 ? |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
E' un problema di dinamica...i numeri interi hanno in genere un range di 2^31 (2^32 gli unsigned), quindi fino a circa 2 (4) giga.
Gli interi a 64 bit arrivano a 2^63 (2^64 gli unsigned), ancora non sufficienti per gestire numeri decimali di venti cifre (2^64 = ~ 1.8*10^19) Non puoi quindi risolvere il tuo problema con i numeri nativi del c; devi operare direttamente sulle stringhe ed "emulare" la matematica (ringrazia che ti hanno chiesto solo sottrazioni). Probabilmente il problema è studiato ad hoc per obbligarti a usare le stringhe per risolverlo.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 Ultima modifica di ilsensine : 21-07-2006 alle 11:31. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Oct 2005
Città: Modena
Messaggi: 1160
|
per i numeri se usi delle variabili int (fino a 16 bit) credo tu possa arrivare fino a 32.767 circa, con un long int (fino a 32 bit) arrivi fino a 2.147.483.647 quindi non so come si possa fare una sottrazzione con numeri di 20 cifre
__________________
Thermaltake Armor Silver#Q6600 @3.3 Ghz - 1.31V#Asus P5Q3 Deluxe wifi-ap @n#2x2 Gb Patriot 1600 Mhz#Palit GTX 570 Sonic edition#WD Caviar blue 500 Gb#Tagan u25 500W#Noctua Nh-d14#Logitech G15 - SPI 34" - |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: May 2004
Messaggi: 2691
|
ciao ho parlato con il mio prof e mi ha detto che effettivamente devo usare le stringhe.. il problema e' che io non so come usarle.. credo vadano convertiti in numero o qualcosa del genere..
fatemi sapere grazie ciao |
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Usando direttamente le stringhe, puoi fare la sottrazione digit per digit come la si farebbe "a mano". Se va bene al tuo prof ...
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: May 2004
Messaggi: 2691
|
online ho trovato questo post
http://groups.google.it/group/it.com...ZfQ4UFyks_AAUi il problema e! analogo ma non ho capito come hanno risolto queste le risposte nodali: Era una CAZZATA!!!!Bastava dichiarare due variabil stringa e due intere,e per ciscuna variabile stringa inserirvi il numero da tastiera(scanf) controllare che la sua lunghezza fosse inferiore od uguale a 20 (funzione length se non erro) usare la funzione atoi per convertirla in intero ed inserirla nella corrispettiva varibile intera,usare la variabile errno (dopo averla settata) per verificare che la stringa fosse o meno convertibile in numero intero(cioè per verificare se atoi è andata a buon fine o no subito dopo averla eseguita),verificare che l'intero è positivo,altrimenti altro messaggio di errore fare lo stesso con l'altra stringa se tutto è andato a buon fine fare le operazioni *+-/ % e poi stampare il risultato a video (printf)!!!!! Per quanto riguarda il long esiste la funzione di conversione (mi affido alle pagine web su cui ho effettuato la ricerca) atol,quindi il problema dei 20 caratteri dovrebbe essere così risolto (con questa semplice modifica al mio precedente programma),infatti se supponiamo che il long sia a 64 bit cioò significa che il max numero rappresentabile avrà 64 "uni",giusto?Ora,applicando le mie conoscenze Altamente Matematico-Fisico-Ingegneristico-Superiori,per calcolare il relativo valore in decimale (supponiamo di utilizzare una base b generica ed un n di bit generico)si fa: somma(da i=0 ad i=n-1,poichè il numero totale dei termini deve essere n) b^i =(b^(n)-1)/(b-1),è chiaro che se banalmente sostituiamo b=2 ed n=64 otteniamo appunto 2^64-1,che quindi dà 20 cifre in base decimale,quindi mi sembra che la cazzata che ho detto sia facilmente riparabile usando il long e l'atol,per il resto direi che è tutto giusto,e quindi la conclusione più logica ora è che ancora una volta la mia Mentalità Altamente Ingegneristica ha trionfato sull cifre,come fare dunque?Sapevo che si poteva fare con le stringhe un controllo simile,ma non mi risultava che esistesse il modo di trasformarle in numeri,tant'è vero che non giuravo,ma poi mi è venuto il sospetto ed ho fatto una ricerca apposita su come convertire una stringa in un numero,una volta realizzato il concetto ho capito tutto |
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: May 2004
Messaggi: 2691
|
Quote:
ciao si ha detto che va bene digit per digit e miha detto che devo far si che il programma ponga 0 se la cifra che tolgo e' maggiore della cifra da cui tolgo qualcuno potrebbe dirmi che listato devo mettere per applicare questo concetto a due cifre e per le restanti cifre lo faccio da solo? grazie mille per il vostro aiuto, davvero preziosissimo ciao |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Aug 1999
Città: Tolmezzo (UD) - Milano
Messaggi: 13744
|
Ciao... qualche tempo fa ho dovuto affrontare un problema simile... soltanto che io dovevo operare su numeri grandi anche 200 cifre e farne somme, sottrazioni, moltiplicazioni, divisioni e radici
Il metodo da me seguito è stato proprio quello che ti hanno consigliato: leggere il numero come fosse una stringa e poi convertirlo con le apposite funzioni in interi o in long da mettere in un array (tieni conto che non è strettamente necessario fare la sottrazione cifra a cifra, ma puoi farla anche a blocchi di più cifre). Il problema di per sè non è troppo difficile, devi solo fare un minimo di attenzione alla conversione e ai riporti (qualora tu operassi in blocchi). Ciao
__________________
...to go where no one has gone before. One ring to rule them all, one ring to find them, one ring to bring them all and in darkness bind them. Caron, non ti crucciare: vuolsi così colà dove si puote ciò che si vuole, e più non dimandare. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: May 2004
Messaggi: 2691
|
ciao il problema e' che io non ho ancora la sufficiente abilità a gestire le stringhe.. cioè ho capito il presupposto teorico ma non riesco ancora a buttare giù il codice senza uno spunto vero e proprio..
se me lo facessi digit per digit puoi dirmi come verrebbe per il primo digit ? in modo che poi perle altre 20 me lo riadatto da solo.. altrimenti avresti ancora il tuo vecchio programma da mostrarmi? grazie Andrea |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Aug 1999
Città: Tolmezzo (UD) - Milano
Messaggi: 13744
|
Io mio vecchio programma ce l'ho... ma credo sia un po' troppo complicato per spiegarti la cosa: io facevo tutto con blocchi di 8 cifre.
Cifra per cifra potresti fare in questo modo: - Leggi il primo numero da input (come stringa) e verifichi che sia lungo 20 caratteri; - Leggi il secondo numero da input e verifichi che sia lungo 20 caratteri o meno; - Usando la funzione "atoi" dentro ad un for converti carattere per carattere la stringa in interi, che metti in un array (lo fai per entrambi i numeri) - Con una funzione costruita ad hoc esegui la sottrazione tra i due array, facendo attenzione ai riporti e alla lunghezza dei due array; se entrambi gli array sono di 20 cifre devi controllare se il sottraendo non sia più grande del minuendo (se non sbaglio in questo caso devi restituire 0). Per la conversione da carattere a intero puoi usare la funzione atoi: http://www.cplusplus.com/ref/cstdlib/atoi.html Per conoscere la lunghezza di una stringa puoi usare la funzione strlen: http://www.cplusplus.com/ref/cstring/strlen.html Per gestire gli array di interi, visto che i numeri contenuti possono andare solo da 0 a 9 (anche in negativo, durante l'operazione), puoi utilizzare come terminatore del numero un qualsiasi intero >= 10 Dovrei averti dato una buona base di partenza, ma se serve altro aiuto non c'è problema. Ciao
__________________
...to go where no one has gone before. One ring to rule them all, one ring to find them, one ring to bring them all and in darkness bind them. Caron, non ti crucciare: vuolsi così colà dove si puote ciò che si vuole, e più non dimandare. |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: May 2004
Messaggi: 2691
|
si mi hai effettivamente dato un validissimo aiuto
provo a buttare giù qualcosa e poi ve lo riporto qui intanto ancora grazie ciao Andrea |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: May 2004
Messaggi: 2691
|
Quote:
hai pvt |
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 1059
|
raga ma la funzione atoi non coverte una <<stringa>> in un numero???
cioè con i singoli caratteri non funziona o sbaglio? |
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: May 2006
Città: Salerno
Messaggi: 936
|
secondo me conviene fare qualcosa tipo
Codice:
string numero1,numero2;
int j=1;
bool impossibile;//vale true se numero1>numero2
bool riporto;//per il do while del riporto
cout << "Inserire i due numeri:\n";
cin >> numero1 >> numero2;
int n1,n2, ris[20];
if(strlen(numero1)==20 && strlen(numero2)<=20)
{
for(int i=19;i>=0;i--)//for inverso
{
switch(numero1[i])
{
case '0':
n1=0;
break;
case '1':
n1=1;
break;
//...
}
switch(numero2[i])
{
//come prima
}
if(i==0 && n1<n2)//verifica se il 1° numero è maggiore del 2°
impossibile=true;
else
{
riporto=false;
if(n1<n2)
{
riporto=true;
n1+=10;
do{
riporto=false;
switch(numero1[i-j])
{
case '0':
numero1[i-j]='9';
riporto=true;
j++;
break;
case '1':
numero1[i-j]='0';
break;
//...
}
}while(riporto)
j=1;
}
ris[i]=n1-n2;
}
}
}else cout << "0\n";
if(!impossibile)
cout << "Il risultato e': ";
for(int i=0;i<20;i++)
cout << ris[i];
cout << endl;
edit: e se anziche usare un long int usassimo un long double, visto che ha (mi sembra) 21 cifre decimali? Ultima modifica di AngeL) : 22-07-2006 alle 10:33. |
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Jun 2002
Città:
Provincia De VaRéSe ~ § ~ Lat.: 45° 51' 7" N Long.: 8° 50' 21" E ~§~ Magica Inter ~ § ~ Detto: A Chi Più Amiamo Meno Dire Sappiamo ~ § ~ ~ § ~ Hobby: Divertimento allo Stato Puro ~ § ~ ~ § ~ You Must Go Out ~ § ~
Messaggi: 8896
|
soluzione del mio neurone dice:
usare tre numeri interi da 32 bit dovrebbe essere anche molto più veloce che accedere a una stringa .. perchè se riesci a caricarli nei registri son schegge rispetto che accedere in memoria e usare una stringa che ne dite come soluzione? ho vinto qualche cosa? ~§~ Sempre E Solo Lei ~§~
__________________
Meglio essere protagonisti della propria tragedia che spettatori della propria vita
Si dovrebbe pensare più a far bene che a stare bene: e così si finirebbe anche a star meglio. Non preoccuparti solo di essere migliore dei tuoi contemporanei o dei tuoi predecessori.Cerca solo di essere migliore di te stesso |
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: May 2006
Città: Salerno
Messaggi: 936
|
Quote:
NO!! |
|
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Jun 2002
Città:
Provincia De VaRéSe ~ § ~ Lat.: 45° 51' 7" N Long.: 8° 50' 21" E ~§~ Magica Inter ~ § ~ Detto: A Chi Più Amiamo Meno Dire Sappiamo ~ § ~ ~ § ~ Hobby: Divertimento allo Stato Puro ~ § ~ ~ § ~ You Must Go Out ~ § ~
Messaggi: 8896
|
Quote:
![]() ~§~ Sempre E Solo Lei ~§~
__________________
Meglio essere protagonisti della propria tragedia che spettatori della propria vita
Si dovrebbe pensare più a far bene che a stare bene: e così si finirebbe anche a star meglio. Non preoccuparti solo di essere migliore dei tuoi contemporanei o dei tuoi predecessori.Cerca solo di essere migliore di te stesso |
|
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Aug 1999
Città: Tolmezzo (UD) - Milano
Messaggi: 13744
|
Quote:
__________________
...to go where no one has gone before. One ring to rule them all, one ring to find them, one ring to bring them all and in darkness bind them. Caron, non ti crucciare: vuolsi così colà dove si puote ciò che si vuole, e più non dimandare. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 02:08.




















