ruby:在 ruby​​ 中从浮点转换为整数会产生奇怪的结果

发布于 2024-10-21 11:21:51 字数 254 浏览 5 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萝莉病 2024-10-28 11:21:51

其实,这一切都有道理。

因为 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 various x, 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 a 1/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.

栀梦 2024-10-28 11:21:51

由于浮点计算中的截断错误,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

追星践月 2024-10-28 11:21:51

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

>> sprintf("%.16f", 10015.8*100.0)
=> "1001579.9999999999000000"

Float#to_i 将其截断为 1001579。

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

>> sprintf("%.16f", 10015.8*100.0)
=> "1001579.9999999999000000"

And Float#to_i truncates this to 1001579.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文