Pow implementation for double
-
21-06-2021 - |
سؤال
I am developing a code that will be used for motion control and I am having a issue with the pow function. I am using VS2010 as IDE.
Here is my issue: I have:
double p = 100.0000;
double d = 1000.0000;
t1 = pow((p/(8.0000*d),1.00/4.000);
When evaluating this last function, I don't get the better approximation as result. I am getting a 7 decimal digits correct, and the consequent digits are all trash. I am guessing that pow function only casts any input variable as float and proceds with calculation.
- Am I right?
- If so, is there any code I can get "inspired" with to reimplement pow for a better precision?
Edit: Solved.
After all, I was having problems with FPU config bits, caused by Direct3D which was being used by OGRE 3D framework.
If using OGRE, on the config GUI, just set "Floating-point mode=Consistent".
If using raw Direct3D, when calling CreateDevice, make sure to pass "D3DCREATE_FPU_PRESERVE" flag to it.
Original post:
You may be using a libray that is changing the default precision of the FPU to single-precision. Then all floating-point operations, even on doubles, will actually be performed as single-precision operations.
As a test, you can try calling _controlfp( _CW_DEFAULT, 0xfffff ); (you need to include ) before performing the calculation to see if you get the correct result. This will reset the floating-point control word to default values. Note that it will reset other settings as well, which may cause issues.
One common library that changes the floating-point precision is Direct3D 9 (and maybe other versions too): By default, it changes the FPU to single-precision when creating a device. If you use it, specify the flag D3DCREATE_FPU_PRESERVE when creating the device to prevent it from changing the FPU precision.
المحلول
You may be using a libray that is changing the default precision of the FPU to single-precision. Then all floating-point operations, even on double
s, will actually be performed as single-precision operations.
As a test, you can try calling _controlfp( _CW_DEFAULT, 0xfffff );
(you need to include <float.h>
) before performing the calculation to see if you get the correct result. This will reset the floating-point control word to default values. Note that it will reset other settings as well, which may cause issues.
One common library that changes the floating-point precision is Direct3D 9 (and maybe other versions too): By default, it changes the FPU to single-precision when creating a device. If you use it, specify the flag D3DCREATE_FPU_PRESERVE
when creating the device to prevent it from changing the FPU precision.
نصائح أخرى
How did you determine you're only getting 7 digits of precision? Are you printing t1
and specifying the correct output format? On my machine, with VS2010, the following code:
int main()
{
double p = 100.0000;
double d = 1000.0000;
double t1 = pow(p/(8.0000*d),1.00/4.000);
printf("t1=%.15f\n", t1); // C
std::cout << "t1=" << std::setprecision(15) << t1 << '\n'; // C++
}
Produces this output:
t1=0.334370152488211
t1=0.334370152488211