4

我正在开发一个用于运动控制的代码,但我遇到了 pow 函数的问题。我使用 VS2010 作为 IDE。

这是我的问题:我有:

    double p = 100.0000;
    double d = 1000.0000;
    t1 = pow((p/(8.0000*d),1.00/4.000);

在评估最后一个函数时,我没有得到更好的近似结果。我得到了正确的 7 位十进制数字,随后的数字都是垃圾。我猜 pow 函数只会将任何输入变量转换为浮点数并进行计算。

  1. 我对吗?
  2. 如果是这样,是否有任何代码可以让我得到“启发”来重新实现 pow 以获得更好的精度?

编辑:已解决。

毕竟,我遇到了由 OGRE 3D 框架使用的 Direct3D 引起的 FPU 配置位问题。

如果使用 OGRE,在配置 GUI 上,只需设置“Floating-point mode=Consistent”。

如果使用原始 Direct3D,在调用 CreateDevice 时,请确保将“D3DCREATE_FPU_PRESERVE”标志传递给它。

原帖:

您可能正在使用将 FPU 的默认精度更改为单精度的库。然后,所有浮点运算,即使是双精度运算,实际上都将作为单精度运算执行。

作为测试,您可以尝试调用 _controlfp( _CW_DEFAULT, 0xfffff ); (你需要包括)在执行计算之前,看看你是否得到正确的结果。这会将浮点控制字重置为默认值。请注意,它也会重置其他设置,这可能会导致问题。

一个改变浮点精度的常用库是 Direct3D 9(可能还有其他版本):默认情况下,它在创建设备时将 FPU 更改为单精度。如果使用它,请在创建设备时指定标志 D3DCREATE_FPU_PRESERVE,以防止其更改 FPU 精度。

4

2 回答 2

4

您可能正在使用将 FPU 的默认精度更改为单精度的库。那么所有的浮点运算,即使是在doubles 上,实际上都将作为单精度运算来执行。

作为测试,您可以在执行计算之前尝试调用_controlfp( _CW_DEFAULT, 0xfffff ); (您需要包含<float.h>),看看您是否得到正确的结果。这会将浮点控制字重置为默认值。请注意,它也会重置其他设置,这可能会导致问题。

一个改变浮点精度的常用库是 Direct3D 9(可能还有其他版本):默认情况下,它在创建设备时将 FPU 更改为单精度。如果使用它,请D3DCREATE_FPU_PRESERVE在创建设备时指定标志,以防止它更改 FPU 精度。

于 2012-07-17T15:45:13.373 回答
0

你是如何确定你只得到 7 位数的精度的?您是否打印t1并指定了正确的输出格式?在我的机器上,使用 VS2010,以下代码:

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++
}

产生这个输出:

t1=0.334370152488211
t1=0.334370152488211
于 2012-07-17T15:31:02.980 回答