Nổi tròn trong Ruby


150

Tôi đang gặp vấn đề làm tròn số. Tôi có một số float, mà tôi muốn làm tròn đến một phần trăm số thập phân. Tuy nhiên, tôi chỉ có thể sử dụng .roundmà về cơ bản biến nó thành một int, có nghĩa 2.34.round # => 2. là Có một cách hiệu quả đơn giản để làm một cái gì đó như2.3465 # => 2.35

Câu trả lời:


181

Khi hiển thị, bạn có thể sử dụng (ví dụ)

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

Nếu bạn muốn lưu trữ nó tròn, bạn có thể sử dụng

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

2
Cảm ơn. Tôi đã không nhận ra chạy nước rút sẽ chăm sóc làm tròn cho tôi. sprintf '%.2f', 2.3465cũng hoạt động.

66
value.round (2) tốt hơn giải pháp này
Kit Ho

12
Hãy ghi nhớ rằng 2.3000.round(2) => 2.3sprintf '%.2f', 2.300 => 2.30. Theo tôi đây là một lỗ hổng trong vòng () hoặc nó nên có một tùy chọn để duy trì các số 0 ở cuối.
Excalibur

14
@Excalibur 2.3000.round(2)là một số, không phải là một chuỗi. Không có cách nào mà số đó 2.3khác với 2.30, vì vậy không có cách nào để có một tùy chọn để bảo toàn các số 0 ở cuối. Bạn có thể tạo lớp số_with_significance của riêng mình nhưng sau đó chúng tôi đã có chuỗi.
Roobie Nuby

6
Lưu ý rằng mặc dù điều này không hoạt động cho hai vị trí thập phân '%.3f' % 1.2345, tuy nhiên vẫn có một lỗ hổng (3 vị trí thập phân chứ không phải 2) !! Tương tự sprintfnhư vậy. Coi chừng. Điều đó sẽ trở lại => 1.234 không => 1.235 như mong đợi (iow, sau số thập phân thứ 2, sprintf làm tròn 5 xuống và chỉ làm tròn 6 lên). Đó là lý do tại sao bình luận của Kit Ho ở trên có hơn 25 lượt upvote. An toàn hơn để sử dụng, '%.3f' % 1.2345.round(3)do đó, số được làm tròn đúng .roundtrước, sau đó được định dạng (với các số 0 ở cuối, nếu cần).
likeethesky

392

Truyền đối số vào vòng chứa số vị trí thập phân để làm tròn thành

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

8
Điều này có vẻ hợp lý hơn là nhân, làm tròn và chia. +1
Đánh dấu vào

3
Hmm phương pháp này dường như không có trong ruby ​​1.8.7. Có lẽ trong 1.9?
Brian Armstrong

2
@Brian. Điều này chắc chắn là trong 1.9 và cũng nằm trong đường ray (Câu hỏi này được gắn thẻ)
Steve Weet

3
Phương pháp làm tròn của Ruby 1.8.7 không có khả năng này, thêm tham số làm tròn số thập phân là khả năng 1.9
bobmagoo

1
Lưu ý rằng bạn không nhận được các số 0 ở cuối, vì vậy 1.1.round(2)=> 1.1không1.10
NotAnAmbiTurner

9

bạn có thể sử dụng điều này để làm tròn đến một tù nhân ..

//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          

7

Bạn có thể thêm một phương thức trong Float Class, tôi đã học được điều này từ 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

3

Bạn cũng có thể cung cấp một số âm làm đối số cho roundphương thức để làm tròn đến bội số gần nhất của 10, 100, v.v.

# 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

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


1

Nếu bạn chỉ cần hiển thị nó, tôi sẽ sử dụng trình trợ giúp number_with_precision . Nếu bạn cần nó ở một nơi khác tôi sẽ sử dụng, như Steve Weet đã chỉ ra, roundphương pháp


1
Lưu ý rằng đó number_with_precisionlà phương pháp chỉ Rails.
Smar

0

Đối với ruby ​​1.8.7, bạn có thể thêm đoạn mã sau vào mã của mình:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.