2016-03-19 16 views
5

Mam problem z porównaniem dwóch zmiennych typu "Real". Jedna jest wynikiem operacji matematycznej, przechowywana w zbiorze danych, druga jest wartością pola edycyjnego w postaci, konwertowanego przez StrToFloat i zapisanego w zmiennej "Real". Problem jest następujący: 121,97 not equal to 121,97Delphi - porównanie dwóch zmiennych liczb rzeczywistych

Jak widać, program próbuje mi powiedzieć, że nie jest równa 121,97 do 121,97 ... Przeczytałem this topic, i nie jestem pewien copletely , że to ten sam problem. Gdyby tak było, to nie byłyby to liczby przechowywane w zmiennych jako dokładnie ta sama najbliższa reprezentowalna liczba, która dla 122,97 wynosi 121.96999 99999 99998 86313 16227 83839 70260 62011 71875?

Teraz powiedzmy, że nie są one przechowywane w tym samym najbliższym reprezentowanym numerze. Jak znaleźć, jak dokładnie są przechowywane? Kiedy patrzę w okno debugowania "CPU", jestem kompletnie zagubiony. Widzę adresy, gdzie powinny być te wartości, ale nic nie jest podobne do jakiejś binarnej, szesnastkowej czy jakiejkolwiek reprezentacji rzeczywistej liczby ... Przyznaję, że zaawansowane debugowanie jest dla mnie nieznanym wszechświatem ...

Edytuj: te dwie wartości są naprawdę nieco inne.

enter image description here

OK, nie muszę wszystkiego rozumieć. Chociaż nie mam do czynienia z pieniędzmi, nie będzie maksymalnie 3 miejsc po przecinku, więc „walutą” jest wyjście

BTW: Obliczenia:

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

W tym przypadku jest to 3695 - 3.573,03

+0

Zobacz JIRA RSP-13792. Możesz wywołać funkcję 'comparevalue'. – Magoo

+2

@Magoo Ten raport jest fałszywy. Kompilator zachowuje się poprawnie. –

+1

'StrToFloat' powinien zachowywać się tak, jak mówisz.Ale co z drugą wartością? Jak to jest obliczane. Myślę, że powinieneś skupić się na rzeczywistym problemie, którego nie widzimy. –

Odpowiedz

9

Z nieznanych przyczyn nie można wyświetlić wartości pływającej (pojedynczej/podwójnej lub rzeczywistej48) w postaci heksadecymalnej na liście obserwowanych.

Jednak nadal można wyświetlić reprezentację szesnastkową, wyświetlając ją jako zrzut pamięci.
Oto jak: Dodaj zmienną do listy obserwowanych.
prawym przyciskiem myszy na zegarek -> Edit Watch ...
go zobaczyć jako memory dump

enter image description here

Teraz można porównać dwie wartości w debuggera.

wolno używać pływaków dla kwot pieniężnych
Wiesz oczywiście, że nie należy używać pływaków liczyć pieniądze.
Będziesz mieć kłopoty z zaokrąglaniem i porównywaniem nie będzie działać tak, jak chcesz.
Jeśli chcesz pracować z pieniędzmi, użyj zamiast tego typu currency. Nie ma tych problemów, obsługuje 4 miejsca po przecinku i można je porównać za pomocą operatora = bez problemów z zaokrąglaniem.

W bazie danych używany jest typ danych money lub currency.

+0

Możesz w wielu przypadkach porównać pływaki dla równości –

+0

Tak, ale nie wtedy, gdy pracujesz z pieniędzmi. Zaktualizowano odpowiedź. Jeśli nie wiesz dokładnie, co robisz, porównania równości z pływakami są receptą na katastrofę. – Johan

+0

Dziękuję! Czy można krótko opisać, na co patrzę w pamięci? Przykro mi to mówić, ale nie udało mi się odkryć ... To znaczy - szesnastkowa reprezentacja 122,97 to 0x42f3f0a4 ... –

Powiązane problemy