in reply to Re: [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 you might have to be careful that the compiler doesn't optimise the tmp var away.

Use volatile to force the compiler to avoid optimising the memory lookup away.

  • Comment on Re^2: [Win32, C, and way OT] C floats, doubles, and their equivalence
  • Download Code

Replies are listed 'Best First'.
Re^3: [Win32, C, and way OT] C floats, doubles, and their equivalence
by syphilis (Archbishop) on Jul 20, 2009 at 00:44 UTC
    Use volatile to force the compiler to avoid optimising the memory lookup away

    I think the above suggestion is made in relation to the use of a separate function - which is not the method I've adopted. (I've made use of a temp variable, but it's in the body of the function itself, rather than in a separate function.)

    I find that declaring my temp variable as "volatile" doesn't help me. If I get rid of the #pragma optimize() calls, and declare the temp variable as volatile float temp, the problem remains. Obviously, "volatile" doesn't turn off every kind of optimization, and certainly doesn't turn off the kind of optimization that it needs to (in my case).

    Cheers,
    Rob

      If your code counters what I said, show it.

      Are you saying that the following works:

      #include <stdio.h> cmpFsFd( float s, double d ) { float tmp = (float)d; return s == tmp ? 1 : 0; } int main(void) { double nv = 2.0 / 3; float foo = 2.0 / 3; if( foo == nv ) printf("True "); else printf("False "); if( cmpFsFd( foo, nv )) printf("True\n"); else printf("False\n"); return 0; }

      And that the following doesn't?

      #include <stdio.h> int main(void) { double nv = 2.0 / 3; float foo = 2.0 / 3; volatile float nv_as_float = (float)nv; if( foo == nv ) printf("True "); else printf("False "); if( foo == nv_as_float ) printf("True\n"); else printf("False\n"); return 0; }

      That makes no sense to me.

        No, no - all I was pointing out was that "volatile" was of no use to me - and I certainly don't mean to imply that you claimed it *would* be of any use to me. In the PDL source I've had to use #pragma optimize("", off) to get the desired behaviour. The conditional test that's causing all the problems in the autogenerated bad.xs is:
        if((a_datap)[0] /* ACCESS() */ == (PDL_Float) __privtrans->value )
        where (a_datap)[0] is a float and __privtrans->value is a double. With all but the pre-VC8.0 compilers, that behaves as desired and expected. My initial attempt at a fix (from the replies received here) for the pre-VC8.0 compilers was to replace that with:
        PDL_Float dummy = (PDL_Float) __privtrans->value; if ( (a_datap)[0] /* ACCESS() */ == dummy )
        All of the playing around that I've done with C scripts suggests that that should have worked ... but it didn't. I still got FALSE evaluations when I wanted and expected the evaluation to be TRUE. If I make 'dummy' volatile, that doesn't make any difference. One way I can get that modified code to behave correctly is to turn off optimization using #pragma. That is, for pre-VC8.0 MS compilers, the code (which behaves correctly) is:
        #pragma optimize("", off) PDL_Float dummy = (PDL_Float) __privtrans->value; if ( (a_datap)[0] /* ACCESS() */ == dummy )
        A patch that provides a better fix will always be most welcome. (It may be relevant that optimization is off for some of the other code as well - not just for the creation of the dummy variable and the testing of the == condition. The optimization cannot be turned on/off inside subroutines.)

        Btw, in case there's a need to mention it, the PDL_Float type is typedef'd as follows:
        typedef float PDL_Float;
        Cheers,
        Rob
        UPDATE - this should be reaped. It's the slightly later post that was intended to be sent ... not this. (Not that there's a great deal of difference.)

        No, no - all I was pointing out was that "volatile" was of no use to me - and I certainly don't mean to imply that you claimed it *would* be of any use to me. In the PDL source I've had to use #pragma optimize("", off) to get the desired behaviour. The conditional test that's causing all the problems in the autogenerated bad.xs is:
        if((a_datap)[0] /* ACCESS() */ == (PDL_Float) __privtrans->value )
        where (a_datap)[0] is a float and __privtrans->value is a double. With all but the pre-VC8.0 compilers, that behaves as desired and expected. My initial attempt at a fix (from the replies received here) for the pre-VC8.0 compilers was to replace that with:
        PDL_Float dummy = (PDL_Float) __privtrans->value; if ( (a_datap)[0] /* ACCESS() */ == dummy )
        All of the playing around that I've done with C scripts suggests that that should have worked ... but it didn't. I still got FALSE evaluations when I wanted and expected the evaluation to be TRUE. If I make 'dummy' volatile, that doesn't make any difference. One way I can get that modified code to behave correctly is to turn off optimization using #pragma. That is, for pre-VC8.0 MS compilers, the code (which behaves correctly) is:
        #pragma optimize("", off) PDL_Float dummy = (PDL_Float) __privtrans->value; if ( (a_datap)[0] /* ACCESS() */ == dummy )
        Btw, in case there's a need to mention it, the PDL_Float type is typedef'd as follows:
        typedef float PDL_Float;
        Cheers,
        Rob