Tôi đang sử dụng Ruby 1.8.7 và Rails 2.3.5.Cách đếm số chữ số thập phân trong Float?
Nếu tôi có float như 12.525, làm cách nào để có được số chữ số ở vị trí thập phân? Trong trường hợp này tôi mong đợi để có được một '3' trở lại.
Tôi đang sử dụng Ruby 1.8.7 và Rails 2.3.5.Cách đếm số chữ số thập phân trong Float?
Nếu tôi có float như 12.525, làm cách nào để có được số chữ số ở vị trí thập phân? Trong trường hợp này tôi mong đợi để có được một '3' trở lại.
Đây là một cách tiếp cận rất đơn giản. Theo dõi số lần bạn phải bội số bằng 10 trước khi nó bằng số nguyên tương đương của nó:
def decimals(a)
num = 0
while(a != a.to_i)
num += 1
a *= 10
end
num
end
decimals(1.234) # -> 3
decimals(10/3.0) # -> 16
Giống như này:
theFloat.to_s.split(".")[1].length
Nó không phải là rất đẹp, nhưng bạn có thể chèn nó như là một phương pháp để Float:
class Float
def decimalPlaces
self.to_s.split(".")[1].length
end
end
Cách tiếp cận này cho tôi 14 (10/3,0) nhưng câu trả lời của tôi cho 16. Tôi nghĩ rằng số thập phân lặp lại sẽ là vấn đề bất kể bạn tiếp cận nó như thế nào. –
Vâng, đó là lẻ ... Tôi cần phải sử dụng IRB! – Linuxios
Mỗi cách tiếp cận phụ thuộc vào những thứ khác nhau, vì vậy các câu trả lời khác nhau không quá ngạc nhiên. –
Bạn có thể trừ sàn và sau đó chỉ đếm số ký tự còn lại?
(12,525 - (12.525.floor)) to_s.length-2 => 3
chỉnh sửa:. Nope doesnt làm việc này cho một loạt các lý do, tiêu cực và 0,99999 vấn đề
Chỉ hoạt động ở 1.8. Hãy thử với 1.9. –
Bạn nên rất cẩn thận với những gì bạn muốn. Floating point numbers là tuyệt vời cho mục đích khoa học và chủ yếu là làm việc cho sử dụng hàng ngày, nhưng họ rơi ngoài khá xấu khi bạn muốn biết một cái gì đó như "bao nhiêu chữ số qua thập phân" - nếu chỉ vì họ có about 16 digits total, không phải tất cả chính xác dữ liệu để tính toán của bạn. (Hoặc, một số thư viện thực sự có thể vứt bỏ dữ liệu chính xác về phía cuối của số khi định dạng số cho đầu ra, với lý do là "số làm tròn thân thiện hơn", trong khi thường đúng, có nghĩa là nó có thể nguy hiểm một chút . dựa vào định dạng đầu ra)
Nếu bạn có thể thay thế các số dấu chấm động tiêu chuẩn với lớp BigDecimal
để cung cấp tùy ý chính xác số dấu chấm động, sau đó bạn có thể kiểm tra "thô" số:
> require 'bigdecimal'
=> true
> def digits_after_decimal_point(f)
> sign, digits, base, exponent = f.split
> return digits.length - exponent
> end
> l = %w{1.0, 1.1, 1000000000.1, 1.0000000001}
=> ["1.0,", "1.1,", "1000000000.1,", "1.0000000001"]
> list = l.map { |n| BigDecimal(n) }
=> [#<BigDecimal:7f7a56aa8f70,'0.1E1',9(18)>, #<BigDecimal:7f7a56aa8ef8,'0.11E1',18(18)>, #<BigDecimal:7f7a56aa8ea8,'0.1000000000 1E10',27(27)>, #<BigDecimal:7f7a56aa8e58,'0.1000000000 1E1',27(27)>]
> list.map { |i| digits_after_decimal_point(i) }
=> [0, 1, 1, 10]
trong số Tất nhiên, nếu di chuyển đến BigDecimal
làm cho ứng dụng của bạn quá chậm hoặc quá mạnh mẽ với những gì bạn cần, điều này có thể làm phức tạp quá mức mã của bạn vì không có lợi ích thực sự. Bạn sẽ phải quyết định điều gì là quan trọng nhất đối với ứng dụng của bạn.
Câu trả lời của Olexandr không hoạt động đối với số nguyên. Có thể thử như sau:
def decimals(num)
if num
arr = num.to_s.split('.')
case arr.size
when 1
0
when 2
arr.last.size
else
nil
end
else
nil
end
end
Khá một giải pháp thanh lịch! – Linuxios
Cảm ơn, tôi bị kẹt trong tệp trợ giúp ứng dụng của tôi. Rất vui khi có được gọi khi cần. – Reno
Còn (1/3) thì sao? – MrYoshiji