Ruby中浮点的一致舍入

时间:2009-12-23 03:30:56

标签: ruby floating-point rounding

我理解由于浮点的不精确表示,以下代码'感觉'不一致。

"%.1f" % 1.14 # => 1.1
"%.1f" % 1.15 # => 1.1
"%.1f" % 1.16 # => 1.2
"%.0f" % 1.4 # => 1
"%.0f" % 1.5 # => 2
"%.0f" % 1.6 # => 2

但是,有一种简单的方法可以将一致的浮点数舍入为5吗?一种方法可能是明确地进行字符串操作。有没有更简单的方法或现有的图书馆?

4 个答案:

答案 0 :(得分:5)

如果需要小数精度,请使用BigDecimal代替浮点数。

编辑:在将数字传递给%之前,您必须手动将数字舍入到所需的长度,否则在舍入之前它会转换为正常的浮点数。

"%.1f" % BigDecimal('1.15').round(1) => "1.2"
"%.0f" % BigDecimal('1.5').round(0) => "2"

答案 1 :(得分:2)

只需添加一个微小的插条,以确保浮点数略低于0.5的东西刚刚结束。

例如,

x = 1.15
"%.1f" % (1.000001*x)  # include correction for imprecise floating-point.

这足以处理格式化问题,但不太可能导致相关错误。

另外:我之前的问题here的一个明显的后续内容,这很好,但为了完整性而包括在内。

答案 2 :(得分:1)

此示例中的函数roundthis()显示了如何以可控,一致的方式对数字进行舍入。注意小软糖值。尝试运行此示例,不要有软糖,看看会发生什么。

def roundthis(x, m)
    return (x/m+0.50001).floor*m
end

for x in [1.14, 1.15, 1.16]
    print "#{x}   #{roundthis(x, 0.1)}  \n"
end

for x in [1.4, 1.5, 1.6]
    print "#{x}   #{roundthis(x, 1.0)}  \n"
end

这个,放入一个名为roundtest.rb的文件并执行print

bash> ruby roundtest.rb
1.14   1.1  
1.15   1.2  
1.16   1.2  
1.4   1.0  
1.5   2.0  
1.6   2.0  

请注意舍入到最近的2,15,0.005或其他任何内容的容易程度。

答案 3 :(得分:0)

乘以100,然后舍入,然后除以100:

(1.15 * 100).round / 100.0 # => 1.15

它不是很优雅,但它避免使用字符串。