在Ruby中对浮点数进行四舍五入

164
我在四舍五入方面遇到了问题。我有一个浮点数,我想将其四舍五入到小数点后两位。然而,我只能使用.round方法,这基本上将其转换为整数,意味着2.34.round # => 2.。有没有一种简单有效的方法可以实现类似于2.3465 # => 2.35这样的效果?
9个回答

413

向round函数传递一个参数,包含要舍入的小数位数

>> 2.3465.round
=> 2
>> 2.3465.round(2)
=> 2.35
>> 2.3465.round(3)
=> 2.347

9
相较于乘、取整和除法,这种方法看起来更加合理。+1 - Mark Embling
3
这个方法似乎不适用于Ruby 1.8.7,也许在1.9版本中有吧? - Brian Armstrong
2
@Brian。这绝对是在1.9中,也在Rails中(这个问题被标记了)。 - Steve Weet
3
Ruby 1.8.7的round方法没有这个功能,添加小数位四舍五入参数是1.9版本才有的能力。 - bobmagoo
3
注意,使用此方法不能保留末尾的零,因此1.1.round(2)得到的结果是 1.1 而不是 1.10 - NotAnAmbiTurner
显示剩余2条评论

190

显示时,您可以使用(例如)

>> '%.2f' % 2.3465
=> "2.35"

如果你想将其四舍五入后存储,可以使用

>> (2.3465*100).round / 100.0
=> 2.35

2
谢谢。我没意识到sprintf会为我处理四舍五入。sprintf '%.2f', 2.3465也可以。 - Noah Sussman
73
value.round(2)比这个解决方案更好。 - TheOneTeam
12
记住 2.3000.round(2) => 2.3sprintf '%.2f', 2.300 => 2.30。我认为这是 round() 的一个缺陷,或者它应该有一个选项来保留尾随零。 - Excalibur
15
@Excalibur 2.3000.round(2)是一个数字,不是字符串。数字2.32.30没有区别,所以无法保留尾随零的选项。你可以创建自己的numbers_with_significance类,但那时候我们已经有了字符串。 - Roobie Nuby
8
请注意,尽管这对于两位小数有效,但在'%.3f'%1.2345(三个小数位,而不是两个)中存在一个缺陷!!同样适用于sprintf。请注意,这将返回=> 1.234,而不是大多数人期望的=> 1.235(也就是说,在第二个小数位之后,sprintf会将5 向下 四舍五入,只有6才会向上四舍五入)。这就是为什么Kit Ho上面的评论获得了25+赞的原因。更安全的方法是使用'%.3f'%1.2345.round(3),这样数字首先通过.round正确四舍五入,然后进行格式化(如果需要,包括尾部零)。 - likethesky
sprintf 将 0.5 四舍五入到最近的偶数位。'%.3f' % 1.2355'%.3f' % 1.2365 都会得到 "1.236"。.round 将 0.5 向上舍入。 - ralphmerridew

12

你可以使用这个来进行精度四舍五入。

//to_f is for float

salary= 2921.9121
puts salary.to_f.round(2) // to 2 decimal place                   

puts salary.to_f.round() // to 3 decimal place          

6
你可以在Float类中添加一个方法,我从stackoverflow学到了这个方法:
class Float
    def precision(p)
        # Make sure the precision level is actually an integer and > 0
        raise ArgumentError, "#{p} is an invalid precision level. Valid ranges are integers > 0." unless p.class == Fixnum or p < 0
        # Special case for 0 precision so it returns a Fixnum and thus doesn't have a trailing .0
        return self.round if p == 0
        # Standard case  
        return (self * 10**p).round.to_f / 10**p
    end
end

4

你可以将负数作为参数传递给round方法,以便将其四舍五入到最接近的10、100等倍数。

# Round to the nearest multiple of 10. 
12.3453.round(-1)       # Output: 10

# Round to the nearest multiple of 100. 
124.3453.round(-2)      # Output: 100

3

那么 (2.3465*100).round()/100.0 是什么意思呢?


2
def rounding(float,precision)
    return ((float * 10**precision).round.to_f) / (10**precision)
end

1
如果只需要显示它,我会使用 number_with_precision 助手。 如果在其他地方需要它,我会像 Steve Weet 指出的那样使用 round 方法。

1
请注意,number_with_precision 是仅适用于 Rails 的方法。 - Smar

0

对于 Ruby 1.8.7,您可以将以下内容添加到您的代码中:

class Float
    alias oldround:round
    def round(precision = nil)
        if precision.nil?
            return self
        else
            return ((self * 10**precision).oldround.to_f) / (10**precision)
        end 
    end 
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接