2011-08-17 112 views
12

圆形的圆形圆形向上或向下弯曲。我总是需要它圆下来。一种圆形的方法浮动圆形下移

我有解决方案,但我不太喜欢它......也许有更好的办法。

这就是我想要的:

1.9999.round_down(2) 
#=> 1.99 
1.9901.round_down(2) 
#=> 1 

我想出了这个解决办法,但我想知道是否有更好的解决方案(我不喜欢,我转换的浮动两次)。有没有一种方法呢?因为我发现很奇怪我找不到它。

class Float 
    def round_down(n=0) 
    ((self * 10**n).to_i).to_f/10**n 
    end 
end 

谢谢。

+0

我喜欢你的解决方案... – reto

+0

你要什么负数呢?趋向负无穷或趋向于零? – l0b0

+0

这不完全是你想要的(因为你总是会丢失小数部分),但是如果你转换为一个整数,你将总是舍入 - '1.9901.to_i' - 取决于你的场景可以更好。 –

回答

9

根据@kimmmo的回答,这应该会更有效一些:

基于从@steenslag答案
class Float 
    def round_down n=0 
    s = self.to_s 
    l = s.index('.') + 1 + n 
    s.length <= l ? self : s[0,l].to_f 
    end 
end 

1.9991.round_down(3) 
=> 1.999 
1.9991.round_down(2) 
=> 1.99 
1.9991.round_down(0) 
=> 1.0 
1.9991.round_down(5) 
=> 1.9991 

,或者还可能更有效,因为没有字符串转换:

class Float 
    def round_down n=0 
    n < 1 ? self.to_i.to_f : (self - 0.5/10**n).round(n) 
    end 
end 
+0

这个答案也很好。仍然喜欢@ kimmmo他的解决方案,因为它更短,更易于阅读。但这也是一个很好的答案!谢谢 –

+0

@michaelkoper:看看第二个解决方案 - 我认为它更直接,更高效。 – geronime

+3

在我的快速测试中,这个字符串的版本大约是kimmmo的“分裂”版本的两倍,而使用实际数学的第二个版本仍然快4倍。数学:适合数字。 –

36
1.9999.to_i 
#=> 1 
1.9999.floor 
#=> 1 

回答1秒前fl00r

"%.2f" % 1.93213 
#=> 1.93 

@kimmmo是正确的。

class Float 
    def round_down(n=0) 
    self.to_s[/\d+\.\d{#{n}}/].to_f 
    end 
end 
+1

''%.2f“%1.935 => 1.94',提问者希望它返回1.93 –

+0

@ kimmmo,哦,我知道了 – fl00r

8

看起来你只是想后ň

class Float 
    def round_down(n=0) 
    int,dec=self.to_s.split('.') 
    "#{int}.#{dec[0...n]}".to_f 
    end 
end 


1.9991.round_down(3) 
=> 1.999 
1.9991.round_down(2) 
=> 1.99 
1.9991.round_down(0) 
=> 1.0 
1.9991.round_down(10) 
=> 1.9991 

剥离小数(编辑:稍微更有效的版本,没有正则表达式)

+0

嘿,我喜欢这个主意! –

+0

不应该'1.9991.round_down(0)'返回'1'而不是'1.0'? – Mischa

+0

@mischa'1.0'只是表示它仍然是一个浮动。我想你可以在'n == 0'的情况下使用'to_i'来构建函数,但这可能会让某些人头疼。 – brymck

1

在Ruby 1.9:

class Float 
    def floor_with_prec(prec = 0) 
    (self - 0.5).round(prec) 
    end 
end 
+0

'(1.9990 - 0.5).round(2)'=> 1.5(要求它返回1.99) –

+1

@kimmmo对。你可以通过一个小修改来解决这个问题,我想:'(self - 0.5/10 ** prec).round(prec)'。不过,我不确定这是否会因浮点问题而被打败。 – brymck

1
class Float 
    def rownd_down(digits = 1) 
    ("%.#{digits+1}f" % self)[0..-2].to_f 
    end 
end 

> 1.9991.rownd_down(3) 
=> 1.999 
> 1.9991.rownd_down(2) 
=> 1.99 
> 1.9991.rownd_down(10) 
> 1.9991 
-1

这为我工作。

> (1.999).to_i.to_f 

对于围捕你可以只使用

> (1.999+1).to_i.to_f 
0
class Float 
    def round_down(n) 
    num = self.round(n) 
    num > self ? (num - 0.1**n) : num 
    end 
end 

56.0.round_down(-1) = 50。同样适用于负数,如果您同意四舍五入使数字更小:-56.09.round_down(1) = -56.1

0

发现这篇文章有帮助:https://richonrails.com/articles/rounding-numbers-in-ruby

这里是圆上下方法:

class Float 
    def round_down(exp = 0) 
    multiplier = 10 ** exp 
    ((self * multiplier).floor).to_f/multiplier.to_f 
    end 

    def round_up(exp = 0) 
    multiplier = 10 ** exp 
    ((self * multiplier).ceil).to_f/multiplier.to_f 
    end 
end