2016-03-19 29 views
5

Ho un problema con il confronto di due variabili di tipo "reale". Uno è il risultato di un'operazione matematica, memorizzato in un set di dati, il secondo è un valore di un campo di modifica in un modulo, convertito da StrToFloat e memorizzato nella variabile "Reale". Il problema è questo: 121,97 not equal to 121,97Delphi - confronto di due variabili di numeri "reali"

Come si può vedere, il programma sta cercando di dirmi, che 121,97 non è uguale a 121,97 ... Ho letto this topic, e io non sono sicuro copletely , che è lo stesso problema. Se lo fosse, non sarebbero entrambi i numeri memorizzati nelle variabili come un numero rappresentativo esattamente identico, che per 121.97 è 121.96999 99999 99998 86313 16227 83839 70260 62011 71875?

Ora diciamo che non vengono memorizzati come lo stesso numero rappresentabile più vicino. Come faccio a sapere in che modo sono memorizzati esattamente? Quando guardo nella finestra di debug della "CPU", sono completamente perso. Vedo gli indirizzi, dove questi valori dovrebbero essere, ma nulla di simile a qualche binario, esadecimale o qualsiasi rappresentazione del numero reale ... Ammetto che il debug avanzato è un universo sconosciuto per me ...

Modifica: questi due valori sono in realtà leggermente diversi.

enter image description here

OK, non ho bisogno di capire tutto. Anche se io non sto trattando con i soldi, non ci sarà un massimo di 3 cifre decimali, in modo da "moneta" è la via d'uscita

BTW: Il calcolo è:

DATA[i].Meta.UnUsedAmount := DATA[i].AMOUNT - ObjQuery.FieldByName('USED').AsFloat; 

In questo caso è 3695-3573,03

+0

Vedere JIRA RSP-13792. Potresti voler invocare la funzione 'comparevalue'. – Magoo

+2

@Magoo Quella relazione è falsa. Il compilatore si comporta correttamente. –

+1

'StrToFloat' dovrebbe comportarsi come dici tu.Ma per quanto riguarda l'altro valore? Come è calcolato. Penso che dovresti concentrarti sul problema reale, che non possiamo vedere. –

risposta

9

Per ragioni sconosciute, non è possibile visualizzare un valore float (singolo/doppio o real48) come esadecimale nell'elenco di controllo.

Tuttavia, è comunque possibile visualizzare la rappresentazione esadecimale visualizzandola come un dump della memoria.
Ecco come: Aggiungere la variabile all'elenco di controllo.
Fare clic destro sull'orologio -> Modifica Guarda ...
Vedi come memory dump

enter image description here

Ora è possibile confrontare i due valori nel debugger.

Non usare carri per importi monetari
Tu sai, naturalmente, che non si dovrebbe usare galleggianti a contare i soldi.
Arriverete a tutti i tipi di problemi con arrotondamenti e confronti non funzionerà nel modo desiderato.
Se si desidera lavorare con i soldi, utilizzare invece il tipo currency. Non ha questi problemi, supporta 4 cifre decimali e può essere confrontato usando l'operatore = senza problemi di arrotondamento.

Nel proprio database si utilizza il tipo di dati money o currency.

+0

In molti casi è possibile confrontare i float per l'uguaglianza –

+0

Sì, ma non quando si lavora con denaro. Aggiornata la risposta. A meno che tu non sappia esattamente cosa stai facendo, i confronti di uguaglianza con i galleggianti sono una ricetta per il disastro. – Johan

+0

Grazie! Sarebbe possibile descrivere brevemente cosa sto guardando nel dump della memoria? Mi spiace dirlo, ma non ho avuto successo nel capire ... Voglio dire - la rappresentazione esadecimale di 121.97 è 0x42f3f0a4 ... –