如果存储在中间“双”变量中,浮点计算会发生变化

时间:2015-03-29 23:00:18

标签: c++ floating-point double floating-accuracy

我正在尝试编写一个简单的log base 2方法。我知道在计算机上表示像std :: log(8.0)和std :: log(2.0)这样的东西很困难。我也理解std :: log(8.0)/ std :: log(2.0)可能会导致一个非常低于3.0的值。我不明白的是为什么将下面的计算结果放入一个double并使其成为左值然后将其转换为unsigned int会比直接转换公式更改结果。以下代码显示我的测试用例在我的32位debian wheezy机器上反复出现故障,但在我的64位debian wheezy机器上反复传递。

#include <cmath>
#include "assert.h"

int main () {
  int n = 8;
  unsigned int i =
    static_cast<unsigned int>(std::log(static_cast<double>(n)) /
                              std::log(static_cast<double>(2)));
  double d =
    std::log(static_cast<double>(n)) / std::log(static_cast<double>(2));
  unsigned int j = static_cast<unsigned int> (d);
  assert (i == j);
}

我也知道我可以使用位移来以更可预测的方式提出我的结果。我很好奇为什么要使用double来导致操作与操作有任何不同,只是将该值粘贴到堆栈中的double并在堆栈上转换double。

1 个答案:

答案 0 :(得分:6)

在C ++中,允许浮点执行此类操作。

一种可能的解释是,除法的结果在内部以高于double的精度计算,并存储在精度高于double的寄存器中。

直接将此转换为unsigned int会产生不同的结果,首先将其转换为double,然后转换为unsigned int

要确切了解发生了什么,查看编译器为32位大小写生成的程序集输出可能会有所帮助。

毋庸置疑,您不应该编写依赖于浮点运算精确性的代码。