سؤال

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.

  1. Am I right?
  2. 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 doubles, 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top