I'm using the FSINCOS instruction. But I'm facing a problem: if the argument is PI/2 the cosine is not 0, it is something -271.1e-20.

What did I wrong?

I put the OllyDbg screenshots.
Posted on 2004-05-02 11:08:12 by bszente
maybe because your pi/2 is slightly inaccurate? i make pi/2 to be


rather than


so that's a difference of about 2.076867831e-17, could that account for it?
Posted on 2004-05-02 11:28:05 by stormix
It's not the case. I make PI with the following:

fadd st,st ; to obtain 2*pi

I think this would be quite precise (and much faster), than loading constants from memory.
I made this in VC++ to, and it gives something similar for cos(pi/2) ...e-17. Maybe the FPU does not calculate it exactly.

I don't know.
Posted on 2004-05-02 11:32:02 by bszente
Pi can not be represented exactly with any finite number of digits. The precision of a cosine result approaches the precision of the argument when in the pi/2 range. If you depend on the answer to cos(pi/2) being 0, you should round the answer by a couple of bits.
Posted on 2004-05-02 12:11:48 by Sephiroth3
OK, I understand. I was thinking that I should handle it manually, if I wan't precise 0.
I assume the same is valid also for the FSIN instruction too.

Posted on 2004-05-02 12:16:08 by bszente
I had the same problem with the sine function, but I ignored it since the value in my particular program even when manipulated will be less than zero so it would not affect the application. IF its like that dont worry about it.
Posted on 2004-05-02 21:06:03 by x86asm
maybe because your pi/2 is slightly inaccurate? i make pi/2 to be


That may be fine on paper. Others have computed the value with several million decimal places.

However, the FPU has a limit in accuracy equivalent to approximately 19 significant digits. Converting a string containing more than 18 significant digits to its floating point format would have no effect on the result. The conversion process normally uses the fbld instruction which can only hold a maximum of 18 packed decimal digits anyway.

It's simply a pure waste of time to type more than 18 significant digits in a source code with the expectation that a more accurate value would be obtained when assembled. Some assemblers may even consider leading zeros as part of those 18 maximum digits.

With regards to the value of pi, using the hard coded value in the FPU is the best way to obtain its most accurate one. The value of 1.5707963267948966400 reported for pi/2 by the debugger may seem a bit inaccurate but may simply be due to a conversion from its REAL8 rounded value used by that debugger.

Posted on 2004-05-02 23:32:38 by Raymond
Thanks for all of you for your advices. The problem is clear for me now.
It seems logical to me that the hardcoded value of PI is the best solution, otherwise it would not be implemented in the processor (however there are many unfavorized instruction too :-) ).

Thanks for your contribution.

Posted on 2004-05-03 06:14:52 by bszente