我的c ++代码中有这个计算
r=(float)736778906400/100
现在显然答案应该是7367789064
,但编译器返回7367789056
问题是什么
答案 0 :(得分:5)
当你这样做时:
(float)736778906400/100
您首先将736778906400
投射到float
,然后除以100
,这样您就会遇到多个舍入错误:
736778906400
无法用32位float
(最有可能float
大小)表示;
float(736778906400) / 100
的最终结果无法用32位float
完全表示。
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
。
736778906400
完全可由100
表示,因此此处没有舍入错误。问题来自于IEEE 754的除法算法结束时的舍入。
float
正好是736778911744 / 100
,位于7367789117.44
范围内,因此该值四舍五入为[2^32 + 1, 2^33]
的最接近倍数,即2^(32 - 23) = 2^9 = 512