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.


Log in to reply