Numeric code transferring powerpc to intel gives different results using float

My main problem is how to do arithmetic with floats on x86, like PowerPC, going from Classic MacOS (CodeWarrior) to Windows (VS 2008).

The code in question has a bunch of algorithms that are very iterative and numerically very sensitive.

Typical complex line:

Ims_sd = sqrt((4.0*Ams*sqr(nz)-8.0*(Ams+Dms)*nz+12.0*sqr(Ams)) /
         (4.0*sqr(Ams)*(sqr(nz)-1)) - 
         sqr(Ims_av))*sqrt(nz-1);

It is written using typedef'd floatas the base type.

The transition to doublegives very similar results on both platforms, but, unfortunately, the numbers are unacceptable, so we can not make this simple exit.

Mac code was compiled using CodeWarrior, and just turning off the generation of the FMADD and FMSUB commands had a dramatic effect on the generated numbers. So, the starting point was to look for options for Visual Studio (2008) that seemed most similar - make sure the merged add was to be used. We suspect that the key lies in the behavior of the compiler when allocating intermediate storage in calculations

Currently, the best results are obtained using a combination of SSE2 and /fp:fast. Enabling built-in functions causes the values ​​to drift further from the values ​​of the Mac.

/ fp says it only /fp:strictdisables the smooth add behavior.

MSDN FP10.OBJ " LIBC.LIB, LIBCMT.LIB MSVCRT.LIB." 64- . , , , FP10.OBJ ( verbose linker MSVCRTD.lib).

64- ,

_controlfp_s(&control_word, _PC_64, MCW_PC);

DllMain.

, - () , PowerPC ( ), , PC-Lint. , .

UPDATE:

: , PPC , 64 , x86 FPU ( 4 ).

, SSE2 , (IIRC), .

- 64 ? x64 FP, PPC .

64- , , ( , , ).

, -, , , , . . Mac, , . , , , , , ( !). , , .

+5
3

, , .

, - , .

+3

, ( ), . , , , , , , . , .

(?) IEEE754 , ? , ( , o/s, ) fp.

( ) , int float. C ( , ++) ( , ).

- ( Fortranny) , 4.0 , () , - 4.000000000000000000000000. , Fortran 4- , 3.14159625, 8 pi. .

, , , , .

, , , , , ? , "", , .

+1

GCC 323:

323, x87 gcc ! , x87, , , , ! , , FPU !

, "" / IEEE x87 ; , fldcw - (IIRC, IEEE FP WRT). , - :

  • ( ldresult1), , float ( fresult1).
  • RTNI, op, RTNE, float.
  • , : RTNE float. , ( ) fresult2 < fresult1, , , fresult1 = nextafterf (fresult2, + inf), :
    • ldresult1 == ((long double) fresult1 + fresult2)/2. "" - fresult2.
    • ldresult2 == ((long double) fresult1 + fresult2)/2. "" - fresult1.

, , , -, , , .

: , , sqrt() resolt ( ); , - , , " 1 " (, ). , , , . , ISTR "" -, , OTTOMH.

+1

All Articles