gpt4 book ai didi

c++ - 转换为科学计数法时出现 double 错误

转载 作者:搜寻专家 更新时间:2023-10-31 02:23:49 25 4
gpt4 key购买 nike

我正在构建一个程序,将 double 值转换为科学值格式(尾数、指数)。然后我注意到下面的内容

369.7900000000000 -> 3.6978999999999997428

68600000 -> 6.8599999999999994316

我注意到其他几个值也有相同的模式。最大分数误差为

0.000 000 000 000 001 = 1*e-15

我知道在计算机中表示 double 值的不准确性。这是否可以得出结论,我们将得到的最大小数误差是 1*e-15?这有什么重要意义?

大部分关于栈溢出中浮点精度问题的题我都看完了,但是我没有看到任何关于 64 位最大小数误差的问题。

为了清楚我所做的计算,我也提到了我的代码片段

double norm = 68600000;
if (norm)
{
while (norm >= 10.0)
{
norm /= 10.0;
exp++;
}
while (norm < 1.0)
{
norm *= 10.0;
exp--;
}
}

现在我明白了

norm = 6.8599999999999994316;
exp = 7

最佳答案

您获得的号码与 machine epsilon 有关对于 double 数据类型。

double 有 64 位长,其中 1 位用于符号,11 位用于指数,52 位用于尾数。 double 的值由

给出
1.mmmmm... * (2^exp)

尾数只有 52 位,任何 2^-52 以下的 double 值在添加到 1.0 时将完全丢失,因为它的意义不大。在二进制中,1.0 + 2^-52 将是

1.000...00  + 0.000...01  = 1.000.....01

显然,任何更低的值都不会改变 1.0 的值。您可以在程序中自行验证 1.0 + 2^-53 == 1.0

这个数字 2^-52 = 2.22e-16 称为机器 epsilon 并且是在一次浮点运算期间发生的相对误差的上限用 double 值舍入误差。

类似地,float 在其尾数中有 23 位,因此其机器 epsilon 为 2^-23 = 1.19e-7

你得到 1e-15 的原因可能是因为你执行许多算术运算时错误会累积,但我不能说因为我不知道你正在做的确切计算。


编辑:我已经调查了您的 68600000 问题的相对错误。

首先,您可能有兴趣知道 round-off如果您将计算分成几步,错误可能会改变您的计算结果:

686.0/10.0      = 68.59999999999999431566
686.0/10.0/10.0 = 6.85999999999999943157
686.0/100.0 = 6.86000000000000031974

在第一行中,最接近 68.6 的 double 低于实际值,但在第三行中我们看到最接近 6.86 的 double 更大。

如果我们查看您程序的绝对错误 e_abs = abs(v-v_approx),我们会发现它是

6.8600000 - 6.85999999999999943156581139192 ~= 5.684e-16

但是,相对误差 e_abs = abs( (v-v_approx)/v) = abs(e_abs/v) 将是

5.684e-16 / 6.86  ~=  8.286e-17

这确实低于我们的机器 epsilon 2.22e-16

This如果您想了解有关浮点运算的所有细节,可以阅读这篇著名的论文。

关于c++ - 转换为科学计数法时出现 double 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28846793/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com