C++ 转换为更精确的类型并失去准确性?

标签 c++ floating-point precision

考虑两种计​​算方式:

  1. double 据
    -> 应用 double 临时函数
    -> 返回结果
  2. double 据
    -> 转换为 long double
    -> 应用具有长 double 临时值的函数
    -> 加倍
    -> 返回结果

与第一个解决方案相比,第二个解决方案是否会给出不太准确的结果?如果是,在什么情况下?

最佳答案

是的。证明:令 c = 0x1p-53 + 0x1p-64。在 double 和 long double 中计算 1+c-c-1(常见的 Intel 格式,具有 64 位尾数)。在 double 中,结果为 0,这是数学上精确的答案。在 long double 中,结果是 -0x1p-64,这是错误的(并且在转换为 double 时仍然是错误的)。

在 double 中,1+c 将 1 的 ULP(最小精度单位)的一半略多一点加到 1,因此它产生 1 加上一个 ULP。减去 c 会减去略多于一半的 ULP,因此最接近结果的可表示数字( double )为 1,因此产生 1。然后减去 1 得到 0。

在 long double 中,1+c 加上 0x1p-53 加上 1 的半个 ULP。(在 long double 中,1 的 ULP 是 0x1p-63。)由于结果与两个最接近的可表示数字的距离完全相同(在 long double 中),返回低位为零的那个,1+0x1p-53。那么减去c的确切结果就是1 - 0x1p-64。这是完全可表示的,所以它被返回。最后,减去 1 得到 -0x1p-64。

关于C++ 转换为更精确的类型并失去准确性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10775361/

相关文章:

math - 为什么浮点运算在添加小数时不能给出准确的结果?

c++ - 如何提高乘法的精度?

c++ - 将数据插入有点复杂的数据结构 - C++

algorithm - 有效降低重复运算带来的舍入误差的影响

c++ - C++ 中的浮点异常

php - 从基数解析 float

math - float 学有问题吗?

c++ - 如何将值从主机字节顺序转换为小尾数?

c++ - 绑定(bind)到枚举的类成员

c++ - 如何在 Mac 上使用 C++ 停止正在运行的并行线程?