DirectX math vs. acos

Started by
1 comment, last by Klaatu 20 years, 5 months ago
A fellow programmer has discovered that the following function yields different results if called after a CreateDevice() funciton. The function is called in this manner (note ''real'' is a #define for double) : real crv = .0001, err_tol = .0009, step; step = find_toler_step( crv, err_tol); static real find_toler_step ( real crv, /* I: curvature */ real err_tol /* I: chord height tolerance */) { real step_allowed,krv,exc; krv = (crv>1.E-10)?crv:1.E-10; exc = err_tol * krv; if(fabs(exc)>1.0) step_allowed = 0.0; else step_allowed = 2.0 * sin( acos( 1.0 - exc)) / krv; return (step_allowed); } It appears that the function returns step = 8.48 (expected value) before the CreateDevice() and step = 9.765 (incorrect value) after the call. The above function relies on acos. Does DirectX somehow replace or modify acos()? What''s going on here? Gort...Klaatu, Barada Nikto!
Gort...Klaatu, Barada Nikto!
Advertisement
From the docs to the D3DCREATE flags:

quote:
D3DCREATE_FPU_PRESERVE
Indicates that the application needs either double-precision floating-point unit (FPU) or FPU exceptions enabled. Direct3D sets the FPU state each time it is called.
By default, the pipeline uses single precision. Be sure to use this flag to get double precision. Setting the flag will reduce Direct3D performance.


The latter is the significant part - D3D sets the floating point unit control word to use single precision (the vast majority of game style apps don''t require more).
If you specify the above flag when you create the device, D3D will save the FPU control word at the start of most D3D calls, change the precision to single internally then restore the control word afterwards.

Of course you shouldn''t rely on values being "exact" with floating point anyway (single or double precision).

--
Simon O''Connor
3D Game Programmer &
Microsoft DirectX MVP

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Thanks Simon! After adding the D3DCREATE_FPU_PRESERVE flag, everything works as expected.

Gort...Klaatu, Barada Nikto!
Gort...Klaatu, Barada Nikto!

This topic is closed to new replies.

Advertisement