Very strange problem with comparing floating point numbers

Andrej Mitrovic andrej.mitrovich at gmail.com
Sat Sep 29 18:48:20 PDT 2012


On 9/30/12, Ivan Agafonov <armadil at yandex.ru> wrote:
> // Tell me about this sutation, may be it is a bug?

Reduced:

import std.stdio;
import std.math;

@property float getFloat()
{
    return sqrt(1.1);
}

void main()
{
    writeln(getFloat == getFloat);  // fail
}

Dissasembly:
__Dmain:; Function begin, communal
        enter   12, 0                                   ; 0000 _ C8, 000C, 00
        call    _D4test8getFloatFNdZf                   ; 0004 _ E8,
00000000(rel)
        fstp    dword [ebp-0CH]                         ; 0009 _ D9. 5D, F4
        call    _D4test8getFloatFNdZf                   ; 000C _ E8,
00000000(rel)
        fld     dword [ebp-0CH]                         ; 0011 _ D9. 45, F4
        fxch    st1                                     ; 0014 _ D9. C9
        fucompp                                         ; 0016 _ DA. E9
        fnstsw  ax                                      ; 0018 _ DF. E0
        sahf                                            ; 001A _ 9E
        mov     eax, 1                                  ; 001B _ B8, 00000001
        jpe     ?_033                                   ; 0020 _ 7A, 02
        jz      ?_034                                   ; 0022 _ 74, 02
?_033:  xor     eax, eax                                ; 0024 _ 31. C0
?_034:  call    _D3std5stdio14__T7writelnTbZ7writelnFbZv; 0026 _ E8,
00000000(rel)
        xor     eax, eax                                ; 002B _ 31. C0
        leave                                           ; 002D _ C9
        ret                                             ; 002E _ C3
; __Dmain End of function

Now compare to this which doesn't fail:

void main()
{
    float fx1 = getFloat;
    float fx2 = getFloat;
    writeln(fx1 == fx2);  // pass
}

Dissasembly:
__Dmain:; Function begin, communal
        enter   8, 0                                    ; 0000 _ C8, 0008, 00
        call    _D4test8getFloatFNdZf                   ; 0004 _ E8,
00000000(rel)
        fstp    dword [ebp-8H]                          ; 0009 _ D9. 5D, F8
        call    _D4test8getFloatFNdZf                   ; 000C _ E8,
00000000(rel)
        fstp    dword [ebp-4H]                          ; 0011 _ D9. 5D, FC
        fld     dword [ebp-8H]                          ; 0014 _ D9. 45, F8
        fld     dword [ebp-4H]                          ; 0017 _ D9. 45, FC
        fucompp                                         ; 001A _ DA. E9
        fnstsw  ax                                      ; 001C _ DF. E0
        sahf                                            ; 001E _ 9E
        mov     eax, 1                                  ; 001F _ B8, 00000001
        jpe     ?_033                                   ; 0024 _ 7A, 02
        jz      ?_034                                   ; 0026 _ 74, 02
?_033:  xor     eax, eax                                ; 0028 _ 31. C0
?_034:  call    _D3std5stdio14__T7writelnTbZ7writelnFbZv; 002A _ E8,
00000000(rel)
        xor     eax, eax                                ; 002F _ 31. C0
        leave                                           ; 0031 _ C9
        ret                                             ; 0032 _ C3
; __Dmain End of function

In the first sample the ASM uses fstp for LHS and fld for RHS
(http://en.wikipedia.org/wiki/X86_instruction_listings).

The second one uses fstp twice, then fld twice. I don't know, maybe
this could be a bug. My ASM is weak but I see some difference here..


More information about the Digitalmars-d-learn mailing list