2011-08-17 34 views
12

Làm tròn vòng tròn lên hoặc xuống. Tôi luôn luôn cần nó để làm tròn xuống.Cách để làm nổi các phao xuống

Tôi có giải pháp nhưng tôi không thực sự thích nó ... Có thể có một cách tốt hơn.

Đây là những gì tôi muốn:

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

tôi đã đưa ra giải pháp này nhưng tôi muốn biết nếu có một giải pháp tốt hơn (Tôi không thích mà tôi chuyển đổi phao hai lần). Đã có một phương pháp cho điều này? Bởi vì tôi thấy nó khá kỳ lạ nên tôi không thể tìm thấy nó.

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

Cảm ơn.

+0

Tôi thích giải pháp của bạn ... – reto

+0

nào bạn muốn làm gì với số âm gì?Hướng tới vô cực âm hoặc về không? – l0b0

+0

Nó không chính xác những gì bạn muốn (vì bạn sẽ luôn luôn mất phần thập phân), nhưng nếu bạn chuyển đổi sang một số nguyên bạn sẽ luôn luôn tròn xuống - '1.9901.to_i' - có thể tốt hơn tùy thuộc vào kịch bản của bạn. –

Trả lời

9

Dựa trên câu trả lời từ @kimmmo, điều này sẽ hiệu quả hơn một chút:

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 

hoặc dựa trên câu trả lời từ @steenslag, có lẽ chưa hiệu quả hơn vì không có chuỗi chuyển đổi:

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

Câu trả lời này cũng tốt. Vẫn thích @kimmmo giải pháp của mình vì nó ngắn hơn và dễ đọc hơn. Nhưng đây cũng là một câu trả lời hay! Cảm ơn –

+0

@michaelkoper: hãy xem xét giải pháp thứ hai - tôi nghĩ nó đơn giản hơn nhưng hiệu quả hơn. – geronime

+3

Trong bài kiểm tra tốc độ nhanh của tôi, phiên bản chuỗi này nhanh gấp hai lần phiên bản 'split' của kimono, và phiên bản thứ hai sử dụng toán học thực tế nhanh gấp 4 lần. Toán: tốt cho số. –

4

Bạn có thể sử dụng phương pháp sàn

http://www.ruby-doc.org/core/classes/Float.html#M000142

+0

Sàn nổi # sẽ không bao giờ biến 1,999 thành 1,99. –

+0

Tôi nghĩ rằng sàn là giống như to_i. Nó trả về số nguyên cao nhất. –

+0

Đây là câu trả lời đúng. Bạn có thể đã thêm một ví dụ mặc dù. –

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

đã trả lời 1 sec ago fl00r

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

@kimmmo là đúng.

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

'"% .2f "% 1.935 => 1.94', người hỏi muốn trả lại 1.93 –

+0

@kimmmo, oh, tôi đã nhận được nó – fl00r

8

Hình như bạn chỉ muốn dải số thập phân sau khi n

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 

(Chỉnh sửa: phiên bản hơi hiệu quả hơn mà không regexp)

+0

Xin chào, tôi thích ý tưởng này! –

+0

Không nên '1.9991.round_down (0)' return '1' thay vì' 1.0'? – Mischa

+0

@mischa '1.0' có nghĩa là nó vẫn là một phao. Tôi cho rằng bạn có thể xây dựng trong chức năng để sử dụng 'to_i' nếu' n == 0', nhưng điều đó có lẽ có thể khiến một người nào đó đau đầu. – brymck

1

Trong 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 (người hỏi muốn trả lại 1,99) –

+1

@kimmmo Đúng. Bạn có thể nhận được xung quanh đó với một sửa đổi nhỏ, tôi nghĩ rằng: '(tự - 0,5/10 ** trước) .round (trước)'. Tôi không chắc liệu điều này sẽ bị đánh đập bởi các vấn đề dấu chấm động, mặc dù. – 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

này đã làm việc cho tôi.

> (1.999).to_i.to_f 

Đối với làm tròn lên bạn chỉ có thể sử dụng

> (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. Cũng làm việc với số âm, nếu bạn đồng ý làm tròn số làm cho một số nhỏ hơn: -56.09.round_down(1) = -56.1.

0

Tìm thấy bài viết này hữu ích: https://richonrails.com/articles/rounding-numbers-in-ruby

Dưới đây là vòng lên xuống phương pháp:

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 
Các vấn đề liên quan