ree-1.8.7-2010.02 :003 > (10015.8*100.0).to_i
=> 1001579
ree-1.8.7-2010.02 :004 > 10015.8*100.0
=> 1001580.0
ree-1.8.7-2010.02 :005 > 1001580.0.to_i
=> 1001580
红宝石1.8.7产生相同的。 有谁知道如何根除这种异端邪说? =)
答案 0 :(得分:6)
实际上,所有这些都是有道理的。
因为各种 1 / 2 ** x
< x
的 0.8 无法准确表示/ em>,它必须大致表示,并且它恰好小于 10015.8。
所以,当你打印它时,它会合理地完成。
如果将其转换为整数但未添加 0.5, ,则会将 .79999999 ... 截断为的 0.7 强>
当你输入 10001580.0, 时,它具有所有格式的完全表示,包括float和double。因此,您没有看到值的截断比下一个积分步骤略微小一些。
浮点不是不准确的,只是对可以表示的内容有限制。是的,FP 完全准确但不一定能代表我们可以轻松输入的每个数字 10。 (更新/澄清:讽刺,具有讽刺意味,它可以精确地表示每个整数,因为每个整数都有 2 ** x
组合,但“每个分数”都是另一个故事。只有某些小数部分可以准确使用 1/2**x
系列撰写。)
实际上,JavaScript实现对所有数值使用浮点存储和算术。这是因为FP硬件为整数产生了精确的结果,因此这使得JS人员使用现有硬件(当时)几乎完全32位的机器进行52位数学运算。
答案 1 :(得分:3)
由于浮点计算中的截断错误,10015.8 * 100.0实际上计算为1001579.999999 ...因此,如果您只是应用to_i,它会切断小数部分并返回1001579
答案 2 :(得分:1)
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
>> sprintf("%.16f", 10015.8*100.0)
=> "1001579.9999999999000000"
Float#to_i
将此截断为1001579。