如果为正,则向上舍入浮动,如果为负,则向下舍入到设定的小数位数

时间:2016-06-03 13:50:54

标签: ruby math

我处理的经过时间应始终为小数点后1位,但过去的时间需要向下舍入(因此0.33小时为0.4,-0.33小时为-0.4)。

我简要地写了以下内容,但感觉不够优雅。有没有更明显或更多的方式来做到这一点?

def ceil_to_digits(n, digits = 1)
  digits = 10.0 ** digits
  if n > 0                   
    return (n * digits).ceil / digits   
  else                       
    return (n * digits).floor / digits  
  end   
end

n = 0.333
ceil_to_digits(n, 1) => 0.4
ceil_to_digits(n, 2) => 0.34

n = -0.333
ceil_to_digits(n, 1) => -0.4
ceil_to_digits(n, 2) => -0.34

3 个答案:

答案 0 :(得分:4)

BigDecimal有各种不同的rounding modes。在这种情况下,ROUND_UP可以解决您的问题:

require 'bigdecimal'

def ceil_to_digits(n, digits = 1)
  BigDecimal.new(n, 0).round(digits, :up)
end

n = 0.333
ceil_to_digits(n, 1) #=> 0.4
ceil_to_digits(n, 2) #=> 0.34

n = -0.333
ceil_to_digits(n, 1) #=> -0.4
ceil_to_digits(n, 2) #=> -0.34

答案 1 :(得分:1)

您可以使用圆函数简化它:

(n * 10).round / 10.0

此外round取数字位数:

n.round(1)

+0.37.round(1) # +0.4
-0.37.round(1) # -0.4

了解更多信息:http://ruby-doc.org/core-1.9.3/Float.html#method-i-round

修改

鉴于您正在寻找非标准的舍入,您可以做很多事情来改进您的代码段。也许:

((n * 10.0).send(n > 0 ? :ceil : :floor)) / 10.0

答案 2 :(得分:0)

我认为你的方法很好。如果你想缩短它,你可以写下以下内容。

def ceil_to_digits(n, digits = 1)
  x = 10.0 ** digits
  (n*x).send(n > 0 ? :ceil : :floor)/x
end

n = 0.333
ceil_to_digits(n, 1) #=> 0.4
ceil_to_digits(n, 2) #=> 0.34

n = -0.333
ceil_to_digits(n, 1) #=> -0.4
ceil_to_digits(n, 2) #=> -0.34