C ++ cast float错误地改变了数字

时间:2017-06-09 09:20:18

标签: c++

我的c ++代码中有这个计算 r=(float)736778906400/100现在显然答案应该是7367789064,但编译器返回7367789056问题是什么

1 个答案:

答案 0 :(得分:5)

当你这样做时:

(float)736778906400/100

您首先将736778906400投射到float,然后除以100,这样您就会遇到多个舍入错误:

  1. 736778906400无法用32位float(最有可能float大小)表示;

  2. float(736778906400) / 100的最终结果无法用32位float完全表示。

  3. 将736778906400表示为float

    假设您使用的标准体系结构使用float的{​​{3}} 32位浮点值,则只能表示-16777216+16777216之间的确切整数值({ {1}},因为32位IEEE浮点的尾数为23位)。

    2^24属于736778906400范围内,因此该数字将四舍五入为[2^39 + 1, 2^40]的最接近倍数,即2^(39 - 23) = 2^16 = 65536。您可以通过执行以下操作来检查:

    736778911744

    IEEE 754的尾数为52位,因此它可以精确地存储float x = 736778906400; -2^53之间的整数值,因此您可以轻松地准确存储2^53 里面的`double。

    有关float的舍入值的更多详细信息,请参阅double

    分部736778911744乘100

    {p> 736778906400完全可由100表示,因此此处没有舍入错误。问题来自于IEEE 754的除法算法结束时的舍入。

    float正好是736778911744 / 100,位于7367789117.44范围内,因此该值四舍五入为[2^32 + 1, 2^33]的最接近倍数,即2^(32 - 23) = 2^9 = 512