浮点计算改变,如果存储在中间“双”变量 [英] Floating point computation changes if stored in intermediate "double" variable

查看:105
本文介绍了浮点计算改变,如果存储在中间“双”变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个简单的日志基础2方法。我理解,在计算机上代表像std :: log(8.0)和std :: log(2.0)很困难。我也理解std :: log(8.0)/ std :: log(2.0)可能会导致一个值略低于3.0。我不明白的是为什么把下面的计算结果放到一个双精度值,使其成为一个左值,然后将它转换为一个unsigned int将改变结果相比直接转换公式。下面的代码显示了我的测试用例,它在我的32位debian喘气机上反复失败,但在64位的debian喘气机上反复传递。

I am trying to write a simple log base 2 method. I understand that representing something like std::log(8.0) and std::log(2.0) on a computer is difficult. I also understand std::log(8.0) / std::log(2.0) may result in a value very slightly lower than 3.0. What I do not understand is why putting the result of a the calculation below into a double and making it an lvalue then casting it to an unsigned int would change the result compared to casting the the formula directly. The following code shows my test case which repeatedly fails on my 32 bit debian wheezy machine, but passes repeatedly on my 64 bit debian wheezy machine.

#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的结果int操作是任何不同的将该值放在一个双栈的堆栈和铸造双栈的堆栈。

I also know I can use bit shifting to come up with my result in a more predictable way. I am mostly curious why casting the double that results int he operation is any different than sticking that value into a double on the stack and casting the double on the stack.

推荐答案

在C ++中,浮点是允许做这样的事情。

In C++, floating point is allowed to do this sort of thing.

一个可能的解释是,以比 double 更高的精度内部计算,并以比 double 更高的精度存储在寄存器中。

One possible explanation would be that the result of the division is calculated internally in a higher precision than double, and stored in a register with higher precision than double.

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

Converting this directly to unsigned int gives a different result to first converting this to double and then to unsigned int.

可能有助于查看您的编译器为32位情况生成的汇编输出。

To see exactly what is going on , it might be helpful to look at the assembly output generated by your compiler for the 32-bit case.

不用说,您不应该编写依赖于精确性的代码浮点运算。

Needless to say, you shouldn't write code that relies on exactness of floating point operations.

这篇关于浮点计算改变,如果存储在中间“双”变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆