在字符串流中失去精度

Losing precision in stringstream

本文关键字:失去 精度 字符串      更新时间:2023-10-16

在我的一个应用程序中,我正在尝试将浮点值放入字符串流中,如下所示:

stream << static_cast<float>(double value);

我没有获得整个浮点值,而是只得到它的整数部分。知道为什么会这样吗?

正在强制转换为float - C++将其定义为IEEE 754 32位"单精度"浮点类型。

如果查找此类值的格式,则 32 位将分为三个部分:

  • 23 位用于存储有效值
  • 8 位存储指数
  • 1 位存储符号。
如果您有 23

位来存储有效数,这意味着您可以在有效数中表示的最大值是 2^23。因此,单精度浮点数只有大约 6-9 位精度。

如果浮点值在小数点之前有 9 位或更多位 - 如果它超过 2^23 - 您将永远不会有小数部分。

为了帮助了解这一点,请考虑以下代码:

    void Test()
    {
        float test = 8388608.0F;
        while( test > 0.0F )
        {
            test -= 0.1F;
        }
    }

该代码永远不会终止。每次我们尝试将测试减少 0.1 时,幅度的变化都会丢失,因为我们没有存储它的精度,因此该值最终回到 8388608.0。任何进展都不可能取得,所以它永远不会停止。所有有限精度浮点类型都是如此,因此您会发现 IEEE 754 双精度浮点类型(64 位(也会发生相同的问题,只是值不同,更大。

此外,如果您的目标是保持尽可能多的精度,那么从 double 转换为 float 是没有意义的。 double是 64 位浮点类型; float 是 32 位浮点类型。如果使用 double,则在值足够小的情况下,可以避免大部分截断。