ruby:在 ruby 中从浮点转换为整数会产生奇怪的结果
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
ruby 1.8.7 产生相同的结果。 有谁知道如何根除这种异端吗? =)
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
ruby 1.8.7 produces the same.
Does anybody knows how to eradicate this heresy? =)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
其实,这一切都有道理。
因为 0.8 无法用任意一系列
1 / 2 ** x
精确表示各种 < code>x,它必须近似表示,并且恰好它略小于10015.8。所以,当你只是打印它时,它被合理地舍入。
当您将其转换为整数而不添加 0.5 时,它会将 .79999999... 截断为 .7
当您输入10001580.0时,它在所有格式中都有精确表示,包括浮点数和双精度数。因此,您不会看到值的截断比下一个积分步骤稍小。
浮点并不是不准确,它只是对可以表示的内容有限制。是的,FP完全准确,但不一定代表我们可以使用10基数轻松输入的每个数字。(更新/澄清:嗯,讽刺的是,它可以准确地表示每个整数,因为每个整数都有
2 ** x
组成,但“每个分数”则是另一回事了。某些小数可以使用1/2**x
系列精确组成。)事实上,JavaScript 实现使用浮点存储和算术对于所有数值。这是因为 FP 硬件可以生成精确的整数结果,因此 JS 人员可以在(当时)几乎全部 32 位机器上使用现有硬件进行 52 位数学计算。
Actually, all of this make sense.
Because 0.8 cannot be represented exactly by any series of
1 / 2 ** x
for variousx
, it must be represented approximately, and it happens that this is slightly less than 10015.8.So, when you just print it, it is rounded reasonably.
When you convert it to an integer without adding 0.5, it truncates .79999999... to .7
When you type in 10001580.0, well, that has an exact representation in all formats, including float and double. So you don't see the truncation of a value ever so slightly less than the next integral step.
Floating point is not inaccurate, it just has limitations on what can be represented. Yes, FP is perfectly accurate but cannot necessarily represent every number we can easily type in using base 10. (Update/clarification: well, ironically, it can represent exactly every integer, because every integer has a
2 ** x
composition, but "every fraction" is another story. Only certain decimal fractions can be exactly composed using a1/2**x
series.)In fact, JavaScript implementations use floating point storage and arithmetic for all numeric values. This is because FP hardware produces exact results for integers, so this got the JS guys 52-bit math using existing hardware on (at the time) almost-entirely 32-bit machines.
由于浮点计算中的截断错误,10015.8*100.0实际上计算为1001579.999999...所以如果你简单地应用to_i,它会截掉小数部分并返回1001579
Due to truncation error in float calculation, 10015.8*100.0 is actually calculated as 1001579.999999... So if you simply apply to_i, it cuts off the decimal part and returns 1001579
http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
和
Float#to_i
将其截断为 1001579。http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
And
Float#to_i
truncates this to 1001579.