【问题标题】:printing a float has unexpected value [duplicate]打印浮点数具有意外值[重复]
【发布时间】:2019-01-17 04:52:28
【问题描述】:

为什么在下面的输出中 v 的值中添加了“32”?

int main()
{
    float v = 9.999e8;

    std::cout << "v --> " << v << std::endl;

    std::cout << std::fixed;
    std::cout << "v --> " << v << std::endl;

    return 0;
}

输出:

v --> 9.999e+08
v --> 999900032.000000
             ^^ 

是打印值的人工制品,还是 9.999e+08 不能准确地表示为浮点数?

将 v 更改为 double 可以解决问题,但我想了解实际原因。

强文本

【问题讨论】:

  • 他们所说的。尝试改用double

标签: c++ io floating-point precision


【解决方案1】:

对于float 的常见桌面实现IEEE 754 standard,只有 24 个有效位(和 8 个指数位)。这意味着在没有精度损失的情况下,可以表示的最大连续值是 224,大约为 1.6E7 (1.6•107)。例如,高于此阈值的奇数值不能用这样的float 准确表示,因为最低有效 1 位“脱离”表示。

您的值大约是 1E9 (109),是 60 倍。这意味着该值可以减少 30 左右(四舍五入到最接近的可表示值之后)。请注意,指数位贡献 2exp(没有关于偏移量的吹毛求疵),而不是 10exp

double 有 53 位,对于 1E9 (109) 来说绰绰有余。

【讨论】:

  • @EricPostpischil 很好。修正和澄清。
【解决方案2】:

这是有限精度数学的本质。如果您尝试存储一个无法准确表示的值,则最多只能获得最接近的可表示值。

看看二进制文件:
999900032 -> 111011100110010100001110000000
999900000 -> 111011100110010100001101100000

因此,准确地表示这个数字将需要两个额外的精度位。据推测,这比 float 在您的系统上提供的要多。

【讨论】:

    猜你喜欢
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 2012-07-17
    • 1970-01-01
    相关资源
    最近更新 更多