Mengapa pembagian di Ruby mengembalikan bilangan bulat bukan nilai desimal?


256

Sebagai contoh:

9 / 5  #=> 1

tapi saya harapkan 1.8. Bagaimana saya bisa mendapatkan hasil desimal (non-integer) yang benar? Mengapa itu kembali 1sama sekali?


4
Perhatikan bahwa jika Anda benar-benar menggunakan metode untuk mengembalikan nilai ini, Anda tidak perlu menetapkannya ke variabel; hanya def method; a - b/8; endakan mengembalikan hasil perhitungan dari metode, karena ekspresi terakhir dalam pemanggilan metode adalah nilai kembali.
Phrogz

Jawaban:


268

Itu melakukan pembagian integer. Anda dapat membuat salah satu angka Floatdengan menambahkan .0:

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

10
Ini berfungsi tetapi jawaban to_f di bawah ini tampaknya lebih bermanfaat. Apakah to_f lebih idiomatik di Ruby?
notapatch

9
The .to_fjawabannya adalah lebih baik jika Anda membagi dua variabel yang berisi bilangan bulat, misalnya a.to_f / b. Jika Anda benar-benar membagi dua integer hard-coded (yang mungkin aneh), maka menggunakan 9.0 / 5tidak apa-apa.
jefflunt

350

Itu melakukan pembagian integer. Anda dapat menggunakan to_funtuk memaksa sesuatu ke mode floating-point:

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

Ini juga berfungsi jika nilai Anda adalah variabel, bukan literal. Mengubah satu nilai ke float sudah cukup untuk memaksa seluruh ekspresi ke aritmatika floating point.


1
Ini lebih banyak jawaban "rails" daripada jawaban yang diterima.
Sean Ryan

@muistooshort: saya tidak bisa mengulanginya, maaf. Saya mungkin melakukan sesuatu yang salah.
Joao Costa

4
@SeanRyan Mengapa secara khusus Rails daripada Ruby secara umum? Saya tidak melihat mengapa pengembang (Ruby on) Rails akan melakukan hal khusus ini berbeda dari pengembang Ruby umum. Mungkin saya hanya semantik nitpicking dan kebanyakan orang hanya melihat (Ruby on) Rails dan Ruby sebagai sinonim dalam kasus seperti ini.
Chinoto Vokro

169

Ada juga Numeric#fdivmetode yang bisa Anda gunakan sebagai gantinya:

9.fdiv(5)  #=> 1.8

1
Ini adalah metode tercepat yang saya uji, satu-satunya cara untuk mendapatkan lebih banyak kinerja adalah dengan membagi operan yang mengapung. Saya telah membangun generator bilangan prima di Ruby untuk mempelajari sintaks, sekarang saya mengoptimalkannya untuk mempelajari apa yang paling berhasil. Berikut patokan saya mengumpulkan: memerlukan 'base64'; memerlukan 'zlib'; puts Zlib.inflate (Base64.decode64 ( "eJxlkMEOwiAQRO98hekFuGzxQEwPXvwR01ZqiYHqBk2Tln8XDlWgnDbM25nJonq9NaoD7ZTtR9PigxK09zM7AkgRHieXTYHOsBNf1nklM6B6TuhYpdp + rPgSdiCOi / d / kQ71QBOtAVFLEDly05 + UYQ2H + MckL6z0zioDdJG1S9K1K4iQAW66DhnmiqRYKEJFXMByux + XuOJ2XdO60dKsjC7aBtyTL5O5hLk ="))
Chinoto Vokro

Satu pertanyaan, apakah akan mempertahankan presisi seperti yang kita gunakan 'desimal'?
Adam Aiken

39

Anda dapat memeriksanya dengan irb:

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

26

Anda bisa memasukkan ruby mathn modul .

require 'mathn'

Dengan cara ini, Anda akan dapat membuat pembagian secara normal.

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

Dengan cara ini, Anda mendapatkan pembagian yang tepat (kelas Rasional) hingga Anda memutuskan untuk menerapkan operasi yang tidak dapat dinyatakan sebagai rasional, misalnya Math.sin.


1
Modul mathn sudah tidak digunakan lagi sejak ruby ​​2.2
Meier


6

Fixnum # to_r tidak disebutkan di sini, diperkenalkan sejak ruby ​​1.9. Ini mengubah Fixnum menjadi bentuk rasional. Di bawah ini adalah contoh penggunaannya. Ini juga dapat memberikan pembagian yang tepat selama semua angka yang digunakan adalah 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

Contoh di mana float dioperasikan pada bilangan rasional menutupi hasil ke float.

a = 5.to_r   #=> (5/1) 
a = a * 5.0  #=> 25.0 
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.