ruby:在ruby中从float转换为integer会产生奇怪的结果

时间:2011-03-10 04:53:53

标签: ruby floating-accuracy

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产生相同的。 有谁知道如何根除这种异端邪说? =)

3 个答案:

答案 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。