为了账号安全,请及时绑定邮箱和手机立即绑定

ruby浮点错误

/ 猿问

ruby浮点错误

开满天机 2019-09-03 20:09:15

有人可以解释为什么乘以100会得到一个不太准确的结果但是乘以10会得到更准确的结果吗?


± % sc

Loading development environment (Rails 3.0.1)

>> 129.95 * 100

12994.999999999998

>> 129.95*10

1299.5

>> 129.95*10*10

12995.0


查看完整描述

3 回答

?
杨魅力

如果你手动进行双精度二进制计算,限制为53个有效位,你会看到发生了什么:


129.95 = 1.0000001111100110011001100110011001100110011001100110 x 2 ^ 7


129.95 * 100 = 1.1001011000010111111111111111111111111111111111111111011 x 2 ^ 13


这是56位有效位,所以四舍五入到53位


1.1001011000010111111111111111111111111111111111111111 x 2 ^ 13,等于


12994.999999999998181010596454143524169921875


现在129.95 * 10 = 1.01000100110111111111111111111111111111111111111111111 x 2 ^ 10


这是54位有效位长,因此舍入到53位,它是1.01000100111 x 2 ^ 10 = 1299.5


现在1299.5 * 10 = 1.1001011000011 x 2 ^ 13 = 12995。


查看完整回答
反对 回复 2019-09-03
?
红颜莎娜

首先:您正在查看结果的字符串表示形式,而不是实际结果本身。如果你真的想要比较两个结果,你应该明确地使用格式化两个结果,String#%你应该以相同的方式格式化两个结果。


其次,这就是二进制浮点数的工作原理。它们是不精确的,它们是有限的,它们是二元的。所有这三个意味着你会得到舍入错误,这通常看起来完全随机,除非你碰巧记住了整个IEEE754并且可以在睡眠中背诵它。


查看完整回答
反对 回复 2019-09-03
?
慕田峪4524236

没有完全等于的浮点数129.95。所以你的语言使用的是一个接近它的值。当该值乘以100时,结果接近12995,但它恰好不等于12995.(它也不完全等于它代替的原始值的100倍129.95。)所以你的翻译打印出一个十进制数接近(但不等于)的值,129.95 * 100它表示它不完全是12995.它恰好129.95 * 10恰好等于1299.5。这主要是运气。


最重要的是,从不期望任何浮点运算的平等,只有“接近”。


查看完整回答
反对 回复 2019-09-03
  • 3 回答
  • 0 关注
  • 107 浏览
我要回答

相关问题推荐

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信