提问人:Lapis 提问时间:6/18/2014 最后编辑:sawaLapis 更新时间:6/18/2014 访问量:167
两种舍入方法给出不同的结果
Two rounding methods give different results
问:
两种不同的浮点数舍入方法显示不同的结果。
"%.2f" % 0.015 # => "0.01"
0.015.round(2) # => 0.02
一个是字符串,另一个是浮点数。当舍入除 0.5 以外的任何内容时,它会正确舍入,或者与舍入函数相同。
"%.2f" % 0.01500000000000001 # => "0.02"
此外,它并不总是那样表现:
[0.005, 0.015, 0.025, 0.035, 0.045, 0.055, 0.065, 0.075, 0.085, 0.095].map { |x| "%.2f" % x}
# => ["0.01", "0.01", "0.03", "0.04", "0.04", "0.06", "0.07", "0.07", "0.09", "0.10"]
我不确定这在技术上是否是一个错误,但至少它是非常违反直觉的。有谁知道为什么两种舍入方法的作用如此不同?
答:
3赞
Pyrce
6/18/2014
#1
浮点值并不总是精确存储 - 相反,它们被存储为基数和指数,对于某些数字,它被精确地存储,而另一些则不然。对浮点数的任何修改都可能导致出现非常小的分数。因此,使用不同的舍入函数在边界处对某物进行舍入可以使它在两种可能的结果之间切换。
这样做会给你你想要的结果,因为我猜它的实现方式与浮动圆形方法不同。"%.2f" % 0.015.round(2)
0.02
%.2f
评论
0赞
tadman
6/18/2014
在操作应该如何和类似行为的背后有很多传统,这些传统继承自 C 语言的实现,可能只是始终如一地实现该行为。%
sprintf
0赞
Pyrce
6/18/2014
这很有可能 - 也有可能 %.2f 假设某个字节大小的浮点/双精度值,这与特定 ruby 解释器使用的实际类型不同,并且完成了与 sprintf/C 类型匹配的强制转换。
0赞
Lapis
6/18/2014
我现在使用“%.2f” % 0.015.round(2)作为解决方法。IMO的真正问题是这两种方法之间的意外差异。
1赞
Pyrce
6/18/2014
嗯,一个是对字符串的强制,另一个是对另一个浮点数的强制(然后被强制到字符串以打印到控制台),所以从技术上讲,这两种方法在逻辑上并不等价。
评论