Hi there, i found out that with VC++ 2005, with Maximize Speed (/O2) and /fp: precise options, if you set the rouding mode to CHOP with _controlfp, then the cos,sin,tan, functions return very odd results. For example:
_controlfp_s(NULL,_RC_CHOP, _MCW_RC );
double angle1 = -0.961411;
double res = cos(angle1); // res will be = 0.649981
_controlfp_s(NULL,_RC_NEAR, _MCW_RC );
double angle2 = -0.961411;
double res = cos(angle2); // res will be = 0.572364
The same program under VC++ 2003, with same compiler options (without the /fp: precise that didnt exist in 2003) will give a good result in both modes, thas is 0.572364.
Now, in VC++ 2005, if I set the Maximize Speed (/O2) options + the /fp:fast option, then the results are also good in both modes.
The difference lies in the assembly. With Maximize Speed (/O2) and /fp: precise it compiles the following code and the results are wrong:
004014E7 fld qword ptr [esp+20h]
004014EB call _CIcos (401B9Ch)
With Maximize Speed (/O2) and /fp:fast , then the assembly looks like this (same as VC 2003) and it works fine:
004014E1 fld qword ptr [esp+20h]
004014E5 fld st(0)
Now, if you trace the call to _Clcos, there is a jump to a function called cos_pentium4 that seems to be the buggy function. Because, if you unmask the floating point exceptiong _EM_INVALID like this:
_controlfp_s(NULL, _EM_UNDERFLOW+_EM_OVERFLOW+_EM_ZERODIVIDE+_EM_INEXACT, _MCW_EM);
then the _Clcos funtion will call a cos_default function that will end up using fcos and it works fine again.
Is that a bug in the math lib or a undocumented limitation?
PS: my processor is an Intel Core Duo 2