Durante una delle prove di prima rifinitura del mio programma di contabilità familiare, ho ottenuto un risultato a sorpresa:
Dichiarazioni di Form03.class
PRIVATE f_SaldoFin AS Float
PRIVATE f_Sbilancio AS Float
PRIVATE f_TotResta AS Float
istruzioni inciriminate nella procedura CalcolaSbilancio()
.... bla ..... bla ..... bla .....
f_Sbilancio = f_TotResta - f_SaldoFin
IF f_Sbilancio >= 0 THEN
SbilancioMovvg.Foreground = Color.Foreground 'colore NERO
ELSE
SbilancioMovvg.Foreground = &H00FF0000& 'colore ROSSO
ENDIF
.... bla ..... bla ..... bla .....
Ebbene, allorquando le variabili f_TotResta e f_SaldoFin contengano lo stesso valore (Es. 693,24), la loro differenza ottenuta nella variabile f_Sbilancio non é "0,00", bensì un valore strutturato similmente a "1,123456E05".
Per me il risultato ottenuto è assolutamente inspiegabile. Io ho risolto nel modo seguente:
DIM $_TotResta AS String
DIM $_SaldoFin AS String
'---------------------------------------------------------------------------------------------------------------------
PRINT "Passaggio in CalcolaSbilancio"
' IF f_TotResta = f_SaldoFin THEN
' f_Sbilancio = 0
' ELSE
$_TotResta = CFloat(f_TotResta)
$_SaldoFin = CFloat(f_SaldoFin)
IF $_TotResta = $_SaldoFin THEN
f_Sbilancio = 0
ELSE
f_Sbilancio = f_TotResta - f_SaldoFin
ENDIF
Tuttavia, nonostante che la modalità applicata si sia dimostrata risolutiva, mi resta insoluta la domanda riguardante il perchè del malfunzionamento naturale dell'operazione originaria. ???
Mi potreste aiutare a capire?
Grazie anticipate.
A parte il caso specificato sopra, sto preparando una piccola presentazione del programma per eventuali test di amkici dotati di buona volontà e curiosità. :D
Ciao a tutti.
Grazie per la cortese risposta. Ero sicuro che mi avresti dato il tuo esperto parere. Andando con ordine, come detto nel messaggio d'apertura le due vraibili float, i f_TotResta e f_SaldoFin, contengano lo stesso valore, e ciò l'ho verificato tramite Debug; ho anche guardato il contenuto di f_Sbilancio dopo l'operazione di sottrazione
f_Sbilancio = f_TotResta - f_SaldoFin
ed ho constatato che era diverso da zero. Da ciò ho dedotto che i contenuti di f_TotResta e di f_SaldoFin, pur essendo apparentemente uguali, in realtà non lo sono, ma in fase di Debug non emerge.
Il trasferimento dei contenuti di f_TotResta e di f_SaldoFin in altrettanti campi di tipo stringa serve solamente per testarne l'uguaglianza; infatti il contenuto di questi ultimi non viene assolutamente utilizzato dopo.il problema del punto per la divisione del numero intero da quello decimale nel formatco floating mi é noto, infatti, all'occorrenza, nel programma utilizzo due routine di conversione del punto decimale in virgola e viceversa.
Da tutto quello che mi hai suggerito, tuttavia, penso che non ci sono soluzioni alternative a quella da me adottata.
Grazie ancora. :ciao: :ciao:
Più che soluzioni, questa mi sembra una vera anomalia.
Non sò come tu abbia testato il contenuto delle variabili, ed è quindi possibile che vi siano alcune differenze a livello di decimali, e se tu dici che sono uguali, questo potrebbe non essere proprio vero nei subdecimali.
Se la differenza si evidenzia sugli interi, il problema è che c'è un errore grossolano, altrimenti le differenze dovresti magari trovarle nelle cifre piccole, ad esempio:
DIM v1 AS Float = 1.0000000000000000000000000000000000000000000001
DIM v1 AS Float = 1.0000000000000000000000000000000000000000000002
In questo banale esempio, la differenza stà nella ennesima cifra decimale che, normalmente, viene ignorata per calcoli riferiti su valori monetari.
Un'altra cosa che mi può venire in mente è che è possibile che la cifra superi le dimensioni massime ammesse per un Float, e in questo caso il risultato può essere indefinito.
La conversione che hai fatto in String presumo sia stata effettuata su un valore di decimali definito e abbastanza piccolo (es. 6 decimali a norma bancaria). Se questo è vero, sicuramente il resto è stato giustamente troncato e perso, per cui la comparazione è risultata più idonea al tuo scopo.
Resto comunque dell'idea che vi sia un errore nel tuo codice, perchè diversamente la cosa la vedo alquanto brutta, perchè vorrebbe dire che esiste un problema serio nella gestione dei Float all'interno di Gambas.