红宝石浮点精度
据我了解,Ruby (1.9.2) 浮点数的精度为 15 位十进制数字。因此,我希望将浮点数 x 舍入到小数点后 15 位将等于 x。对于此计算,情况并非如此。
x = (0.33 * 10)
x == x.round(15) # => false
顺便说一下,四舍五入到 16 位会返回 true。
你能向我解释一下吗?
As I understand it, Ruby (1.9.2) floats have a precision of 15 decimal digits. Therefore, I would expect rounding float x to 15 decimal places would equal x. For this calculation this isn't the case.
x = (0.33 * 10)
x == x.round(15) # => false
Incidentally, rounding to 16 places returns true.
Can you please explain this to me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
部分问题在于 0.33 在底层格式中没有精确的表示,因为它无法用一系列 1 / 2n 项来表示。因此,当它乘以 10 时,乘以的数字与 0.33 略有不同。
就此而言,3.3 也没有准确的表示。
第一部分
当数字没有精确的以 10 为基数表示时,在转换尾数中包含信息的最低有效数字时,将会产生余数。这个余数将向右传播,可能永远传播,但这基本上没有意义。此错误的明显随机性与解释您和 Matchu 注意到的明显不一致的舍入的原因相同。那是第二部分。
第二部分
并且此信息(最右边的位)与单个十进制数字传达的信息并不完全对齐,因此十进制数字通常会比它的值稍小,如果原来的精度更高。
这就是为什么转换可能在 15 位数字处舍入为 1,在 16 位数字处舍入为 0.x:因为较长的转换对于尾数末尾右侧的位没有值。
Part of the problem is that 0.33 does not have an exact representation in the underlying format, because it cannot be expressed by a series of 1 / 2n terms. So, when it is multiplied by 10 a number slightly different than 0.33 is being multiplied.
For that matter, 3.3 does not have an exact representation either.
Part One
When numbers don't have an exact base-10 representation, there will be a remainder when converting the least significant digit for which there was information in the mantissa. This remainder will propagate to the right, possibly forever, but it's largely meaningless. The apparent randomness of this error is due to the same reason that explains the apparently-inconsistent rounding you and Matchu noticed. That's in part two.
Part Two
And this information (the right-most bits) is not aligned neatly with the information conveyed by a single decimal digit, so the decimal digit will typically be somewhat smaller than its value would have been if the original precision had been greater.
This is why a conversion might round to 1 at 15 digits and 0.x at 16 digits: because a longer conversion has no value for the bits to the right of the end of the mantissa.
好吧,虽然我不确定 Ruby 内部如何处理浮点数的细节,但我确实知道为什么这段特定的代码在我的盒子上失败了:
无论出于何种原因,第一个浮点数保留了 16 位小数,总共 17 位数字。因此,四舍五入到 15 会丢弃这些数字。
Well, though I'm not certain on the details of how Ruby handles floats internally, I do know why this particular bit of code is failing on my box:
The first float keeps 16 decimal places for a total of 17 digits, for whatever reason. So, rounding to 15 discards those digits.