Tại sao phép chia trong Ruby trả về một số nguyên thay vì giá trị thập phân?


256

Ví dụ:

9 / 5  #=> 1

nhưng tôi mong đợi 1.8. Làm thế nào tôi có thể nhận được kết quả thập phân (không nguyên) chính xác? Tại sao nó trở lại 1ở tất cả?


4
Lưu ý rằng nếu bạn thực sự sử dụng một phương thức để trả về giá trị này, bạn không cần gán nó cho một biến; chỉ đơn giản là def method; a - b/8; endtrả về kết quả tính toán từ phương thức, vì biểu thức cuối cùng trong lệnh gọi phương thức là giá trị trả về.
Phrogz

Câu trả lời:


268

Đó là phân chia số nguyên. Bạn có thể tạo một trong các số a Floatbằng cách thêm .0:

9.0 / 5  #=> 1.8
9 / 5.0  #=> 1.8

10
Điều này hoạt động nhưng câu trả lời to_f dưới đây có vẻ hữu ích hơn. Là to_f thành ngữ hơn trong Ruby?
bố

9
Câu .to_ftrả lời sẽ tốt hơn nếu bạn chia hai biến có chứa số nguyên, vd a.to_f / b. Nếu bạn thực sự chia hai số nguyên được mã hóa cứng (có thể là lạ), thì việc sử dụng 9.0 / 5là ổn.
jefflunt

350

Đó là phân chia số nguyên. Bạn có thể sử dụng to_fđể buộc mọi thứ vào chế độ dấu phẩy động:

9.to_f / 5  #=> 1.8
9 / 5.to_f  #=> 1.8

Điều này cũng hoạt động nếu giá trị của bạn là biến thay vì bằng chữ. Chuyển đổi một giá trị thành float là đủ để ép buộc toàn bộ biểu thức thành số học dấu phẩy động.


1
Đây là câu trả lời "đường ray" nhiều hơn câu trả lời được chấp nhận.
Sean Ryan

@muistooshort: tôi không thể sao chép nó, xin lỗi. Tôi có lẽ đã làm điều gì đó sai.
Joao Costa

4
@SeanRyan Tại sao cụ thể là Rails chứ không phải Ruby nói chung? Tôi không thấy lý do tại sao một nhà phát triển Rails (Ruby on) sẽ làm điều cụ thể này khác với nhà phát triển Ruby nói chung. Có lẽ tôi chỉ là ngữ nghĩa nitpicking và hầu hết mọi người chỉ thấy (Ruby on) Rails và Ruby là đồng nghĩa trong các trường hợp như thế này.
Chinoto Vokro

169

Ngoài ra còn có Numeric#fdivphương pháp mà bạn có thể sử dụng thay thế:

9.fdiv(5)  #=> 1.8

1
Đây là phương pháp nhanh nhất mà tôi đã thử nghiệm, cách duy nhất để có được hiệu năng cao hơn là phân chia các toán hạng được thả nổi để bắt đầu. Tôi đã xây dựng một trình tạo số nguyên tố trong Ruby để tìm hiểu cú pháp, bây giờ tôi đang tối ưu hóa nó để tìm hiểu những gì hoạt động tốt nhất. Dưới đây là điểm chuẩn tôi đặt lại với nhau: require 'base64'; require 'zlib'; puts Zlib.inflate (Base64.decode64 ( "eJxlkMEOwiAQRO98hekFuGzxQEwPXvwR01ZqiYHqBk2Tln8XDlWgnDbM25nJonq9NaoD7ZTtR9PigxK09zM7AkgRHieXTYHOsBNf1nklM6B6TuhYpdp + rPgSdiCOi / d / kQ71QBOtAVFLEDly05 + UYQ2H + MckL6z0zioDdJG1S9K1K4iQAW66DhnmiqRYKEJFXMByux + XuOJ2XdO60dKsjC7aBtyTL5O5hLk ="))
Chinoto Vokro

Một câu hỏi, liệu nó có bảo toàn độ chính xác như chúng ta đang sử dụng 'thập phân' không?
Adam Aiken

39

Bạn có thể kiểm tra nó với irb:

$ irb
>> 2 / 3
=> 0
>> 2.to_f / 3
=> 0.666666666666667
>> 2 / 3.to_f
=> 0.666666666666667

26

Bạn có thể bao gồm các mathnmô-đun ruby .

require 'mathn'

Bằng cách này, bạn sẽ có thể thực hiện phân chia bình thường.

1/2              #=> (1/2)
(1/2) ** 3       #=> (1/8)
1/3*3            #=> 1
Math.sin(1/2)    #=> 0.479425538604203

Theo cách này, bạn có được phép chia chính xác (lớp Rational) cho đến khi bạn quyết định áp dụng một hoạt động không thể được biểu thị như một lý do, chẳng hạn Math.sin.


1
Mô-đun mathn không được dùng nữa kể từ ruby ​​2.2
Meier


6

Fixnum # to_r không được đề cập ở đây, nó được giới thiệu từ ruby ​​1.9. Nó chuyển đổi Fixnum thành dạng hợp lý. Dưới đây là ví dụ về việc sử dụng nó. Điều này cũng có thể phân chia chính xác miễn là tất cả các số được sử dụng là Fixnum.

 a = 1.to_r  #=> (1/1) 
 a = 10.to_r #=> (10/1) 
 a = a / 3   #=> (10/3) 
 a = a * 3   #=> (10/1) 
 a.to_f      #=> 10.0

Ví dụ trong đó một float hoạt động trên một số hữu tỷ bao phủ kết quả để nổi.

a = 5.to_r   #=> (5/1) 
a = a * 5.0  #=> 25.0 
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.