Newsgroup: it.comp.lang.delphi
Titolo: Piccolo problema: Delphi non sa fare i conti

Sebbene alle prime armi con Delphi 7, sto ultimando un software
dedicato che purtroppo presenta un problema con i numeri a virgola
mobile.
Provando ad utilizzare diversi domini di numeri, tra i quali real,
double o extended il risultato è sempre lo stesso.
Mi rivolgo a questo newsgroup perché non so più dove sbattere la
testa.
Ho costruito una procedura per convertire un nome di un file in indice
e viceversa, una sorta di timestamp personalizzato: il nome del file
viene nominato con l'ora attuale (in ore, minuti, secondi e passo).
La procedura legge i file precedenti e successivi converto il nome in
indice;  lo incrementa o decrementa e successivamente lo riconverte in
ore minuti, secondi e passo.
l'algoritmo utilizzato è il seguente:
- Prendi l'indice
- Dividilo per due
- dividilo per 3600
- la parte intera sono le ore, la parte decimale i minuti
- moltiplica la parte decimale per 60
- la parte intera sono i minuti, la parte decimale sono i secondi
- moltiplica la parte decimale per 60
- la parte intera sono i secondi, la parte decimale è il passo
- se passo è 0 allora passo:=0, se è 0,5 allora passo:=1
Utilizzando però le funzioni Trunc e Frac rispettivamente per prendere
la parte intera e decimale delle varie divisioni mi sono accorto che
il compilatore sbarella di brutto.
Se il numero presenta effettivamente una parte intera e una decimale
tutto funziona bene, ma se malauguratamente il numero dopo le
divisioni non presenta decimali ecco che i calcoli vanno a farsi
friggere.
Esempio:
supponiamo che l'indice sia il numero 78120 che corrisponde alle ore
10:51:00 (2*(10*3600)+(51*60)+0)+0)
ebbene delphi calcola così:
78120/2= 39060 <--- ok
39060/3600= 10,85 <--- ok
trunc(10,85)=10 <--- ok
frac(10,85)=0,85 <--- ok
0,85*60=51 <--- ok
trunc(51)=51 <--- ok
frac(51)=1 <--- errore! Deve essere zero!
Ho provato a dichiarae tutte le variabili di appoggio e quelle
definitive real, double o extended ma il problema permane.
Lo stesso problema si manifesta sostituendo la funzione frac con la
sottrazione dei due numeri per ricavare la parte decimale
(numero-trunc(numero)) ho provato anche a sostituire la funzione trunc
con int ma con lo stesso risultato.
Utilizzo un processore AMD Athlon XP 1600+ con sistema operativo
windows XP Pro SP1 e Delphi 7 Professional.
Rigriazio in anticipo chiunque sia in grado di aiutarmi.

Non è un problema di Delphi!
Per i tipi con virgola mobile usa i Currency.
Acqua

 frac(51)=1 <--- errore! Deve essere zero!
// Inizio codice
var
 X: Extended;
begin
 x := 78120;
 x := x / 2;
 x := x / 3600;
 x := Frac(x);
 x := x * 60;
 x := Frac(x);
 label1.Caption := FloatToStrF(x, ffNumber, 18, 18);
end;
Questo codice in Delphi visualizza il valore
0,000000000000021 (piu' o meno, non ho contanto gli
zeri, ma non e' questo l'importante): sono soltanto
questioni di arrotondamenti.
Se, come ti e' stato suggerito da Alessandro, usi il tipo
Currency, tutti i tuoi problemi dovrebbero sparire.
In ogni caso, dai comunque un'occhiata nell'help per tutte le
funzioni di conversione fra tipi (in D7 sono davvero tante!). Alcune
(per esempio DecodeTime e DecodeDate) potrebbero semplificarti
il lavoro.
Ciao.
--
ACSH
[D4]
---------------------------
Chi fa da se'
fatica il doppio

Ringrazio Acqua e ACSH, usando i Currency il problema è risolto.
In effetti non avevo considerato gli arrotondamenti sui vari passaggi
che in Delphi assumono precisione a seconda del tipo usato.
Tenterò anche la strada del DecodeTime e DecodeDate per la conversione
che sono molto interessanti!
Ciao
Luigi

)
  "File deletion is murder..." (Futurama)

 ha scritto nel messaggio
news:3e936cf6.04081...@posting.google.com...
