in reply to Re^2: [Win32, C, and way OT] C floats, doubles, and their equivalence
in thread [Win32, C, and way OT] C floats, doubles, and their equivalence

But for some reason, in the PDL code, creation of the dummy variable is *not*, by itself, sufficient - optimization also needs to be disabled. (I turn it off for the setvaltobad functions, then turn it back on again.)

That's why I moved the temp var and comparison into a separate function; it forces the compiler to use the temp value from memory for the comparison:

; 5 : return s == tmp ? 1 : 0; fld DWORD PTR _s$[ebp] fcomp DWORD PTR _tmp$[ebp] fnstsw ax test ah, 68 ; 00000044H jp SHORT $L809

The problem with the test script is that with optimisations enabled, the newer compiler is able to reduce the whole script to a simple printf( "False" ); printf( "True" ); return 0; (even with the use of the sub) as everything is known at compile time:

; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00 +.30729.01 TITLE C:\test\float.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES _DATA SEGMENT $SG2527 DB 'True ', 00H ORG $+2 $SG2529 DB 'False ', 00H ORG $+1 $SG2531 DB 'True', 0aH, 00H ORG $+2 $SG2533 DB 'False', 0aH, 00H _DATA ENDS PUBLIC _cmpFsFd EXTRN __fltused:DWORD ; Function compile flags: /Ogtpy ; File c:\test\float.c ; COMDAT _cmpFsFd _TEXT SEGMENT tv135 = 8 ; size = 4 _s$ = 8 ; size = 4 _d$ = 12 ; size = 8 _cmpFsFd PROC ; COMDAT ; 4 : float tmp = (float)d; ; 5 : return s == tmp ? 1 : 0; fld DWORD PTR _s$[esp-4] fld QWORD PTR _d$[esp-4] fstp DWORD PTR tv135[esp-4] fld DWORD PTR tv135[esp-4] fucompp fnstsw ax test ah, 68 ; 00000044H jp SHORT $LN3@cmpFsFd mov eax, 1 ; 6 : } ret 0 $LN3@cmpFsFd: ; 4 : float tmp = (float)d; ; 5 : return s == tmp ? 1 : 0; xor eax, eax ; 6 : } ret 0 _cmpFsFd ENDP _TEXT ENDS PUBLIC _main EXTRN _printf:PROC ; Function compile flags: /Ogtpy _TEXT SEGMENT _main PROC ; 11 : double nv = 2.0 / 3; ## ; 12 : float foo = 2.0 / 3; ## All this and ... ; 13 : ; 14 : if( foo == nv ) printf("True "); ## ; 15 : else printf("False "); push OFFSET $SG2529 call _printf ; 16 : ; 17 : if( cmpFsFd( foo, nv ) ) printf("True\n"); ## this are op +timised away! push OFFSET $SG2531 call _printf add esp, 8 ; 18 : else printf("False\n"); ; 19 : ; 20 : return 0; xor eax, eax ; 21 : } ret 0 _main ENDP _TEXT ENDS END

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
RIP PCW

Replies are listed 'Best First'.
Re^4: [Win32, C, and way OT] C floats, doubles, and their equivalence
by syphilis (Archbishop) on Jul 19, 2009 at 11:52 UTC
    That's why I moved the temp var and comparison into a separate function

    Having a separate function is appealing, but not so straightforward to implement. It would be fine if we had an xs file to fiddle with, but the fact that the source file to be amended is a pd file (not an xs file) adds some complexity to the problem. I think it is possible to use the "separate function" approach - though it's actually "separate functions" (plural), as the templating dictates that we'll need separate functions to handle each of the different data types (ie byte, short, long, long long, double - not just float). There's also the issue of the second arg that gets supplied to the "separate function" - it could be a UV or an IV, not necessarily an NV, so we need to accommodate that as well (probably not difficult).

    It's a much simpler solution if one instead just adds a dummy variable and turns off optimization - which seems to work quite well.

    Cheers,
    Rob