Embarcadero in der Matrix - Ein Paradigmenwechsel in Boolscher Logik
-
Wir trafen auf folgendes Problem, festgestellt in XE2 und XE10.
double valA, valB; valA = 1000; valB = valA / 1000.0; if ( (valA / 1000.0) == 1.0) { asm nop; } else { asm nop; }
Der Ausdruck im IF mit "valA" wird FALSE und es wird der ELSE-Zweig betreten. Untersucht man den Ausdruck ist er zwar TRUE, aber es wird der falsche Code ausgeführt.
Optimierungen haben wir deaktiviert. Compiler BCC32.
Was zum Teufel ist das?
-
Du kannstvdir ja mal den ausgespuckten assemblercode anschauen oder ihn hier posten.
-
Bin nicht wirklich bewandert mit ASM:
main.cpp.1382: 004B94A5 33C0 xor eax,eax 004B94A7 8945DC mov [ebp-$24],eax 004B94AA C745E000408F40 mov [ebp-$20],$408f4000 main.cpp.1384: 004B94B1 DB2DDC944B00 fld tbyte ptr [$004b94dc] 004B94B7 DC4DDC fmul qword ptr [ebp-$24] 004B94BA D905E8944B00 fld dword ptr [$004b94e8] 004B94C0 D9C9 fxch st(1) 004B94C2 DAE9 fucompp 004B94C4 DFE0 fstsw ax 004B94C6 F6C444 test ah,$44 004B94C9 7A03 jp $004b94ce main.cpp.1386: 004B94CB 90 nop main.cpp.1387: 004B94CC EB01 jmp $004b94cf main.cpp.1390: 004B94CE 90 nop main.cpp.1393: 004B94CF 896DFC mov [ebp-$04],ebp
-
int02h schrieb:
if ( (valA / 1000.0) == 1.0)
Da ist das Problem. Gleitkommazahlen und
==
vertragen sich nicht.Nimm dir mal etwas Zeit und lies das hier:
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/Bruce Dawson schrieb:
Comparing for equality
Floating point math is not exact. Simple values like 0.1 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations or the precision of intermediates can change the result. That means that comparing two floats to see if they are equal is usually not what you want. GCC even has a warning for this: “warning: comparing floating point with == or != is unsafe”.
-
Danke für den interessanten Beitrag.
Benutzt man
if (valB == 1000.0)
funktioniert es.
-
int02h schrieb:
Benutzt man
if (valB == 1000.0)
funktioniert es.
Hast du meinen Post überhaupt gelesen?
Faustregel: wenn du Gleitkommazahlen mit
==
oder!=
vergleichst, machst du es falsch.