ทำไมการหารใน Ruby ถึงส่งคืนจำนวนเต็มแทนค่าทศนิยม


256

ตัวอย่างเช่น:

9 / 5  #=> 1

1.8แต่ผมคาดว่า ฉันจะรับผลลัพธ์ทศนิยม (ไม่ใช่จำนวนเต็ม) ที่ถูกต้องได้อย่างไร ทำไมมันกลับมา1เลย?


4
โปรดทราบว่าถ้าคุณใช้วิธีการคืนค่านี้จริง ๆ แล้วคุณไม่จำเป็นต้องกำหนดมันให้กับตัวแปร ก็def method; a - b/8; endจะกลับมาผลจากการคำนวณจากวิธีการที่เป็นการแสดงออกสุดท้ายในการเรียกวิธีเป็นค่าตอบแทน
Phrogz

คำตอบ:


268

มันกำลังทำการหารจำนวนเต็ม คุณสามารถสร้างหนึ่งในตัวเลขFloatโดยเพิ่ม.0:

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

10
วิธีนี้ใช้งานได้ แต่คำตอบ to_f ด้านล่างมีประโยชน์มากกว่า to_f มีความหมายมากกว่าในทับทิมหรือไม่
notapatch

9
คำตอบที่ดีกว่าถ้าคุณกำลังหารสองตัวแปรที่มีจำนวนเต็มเช่น.to_f a.to_f / bหากคุณกำลังหารจำนวนเต็มจำนวนฮาร์ดโค้ดสองตัว (ซึ่งอาจแปลก) การใช้9.0 / 5ก็ดี
jefflunt

350

มันกำลังทำการหารจำนวนเต็ม คุณสามารถใช้to_fเพื่อบังคับให้สิ่งต่าง ๆ เข้าสู่โหมดจุดลอยตัว:

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

สิ่งนี้จะทำงานหากค่าของคุณเป็นตัวแปรแทนที่จะเป็นตัวอักษร การแปลงค่าหนึ่งไปเป็นทศนิยมนั้นเพียงพอที่จะบีบบังคับนิพจน์ทั้งหมดเป็นเลขทศนิยม


1
นี่คือคำตอบ "ทางรถไฟ" มากกว่าคำตอบที่ยอมรับ
Sean Ryan

@muistooshort: ฉันไม่สามารถทำซ้ำได้ขอโทษ ฉันอาจทำสิ่งผิดปกติ
Joao Costa

4
@SeanRyan ทำไม Rails เป็นพิเศษมากกว่า Ruby ทั่วไป? ฉันไม่เห็นว่าทำไมผู้พัฒนา Rails (Ruby on) จะทำสิ่งนี้แตกต่างจากนักพัฒนา Ruby ทั่วไป บางทีฉันอาจจะแค่เติมความหมายและคนส่วนใหญ่ก็เห็น (Ruby on) Rails และ Ruby เป็นคำพ้องความหมายในกรณีเช่นนี้
Chinoto Vokro

169

นอกจากนี้ยังมีNumeric#fdivวิธีการที่คุณสามารถใช้แทน:

9.fdiv(5)  #=> 1.8

1
นี่เป็นวิธีที่เร็วที่สุดที่ฉันทดสอบวิธีเดียวที่จะทำให้ได้ประสิทธิภาพมากขึ้นคือการแบ่งตัวถูกดำเนินการที่เริ่มต้นด้วยการลอยตัว ฉันได้สร้างตัวสร้างหมายเลขเฉพาะใน Ruby เพื่อเรียนรู้ไวยากรณ์ตอนนี้ฉันกำลังปรับให้เหมาะสมเพื่อเรียนรู้ว่าอะไรทำงานได้ดีที่สุด นี่คือมาตรฐานที่ผมใส่กัน: require 'base64'; ต้อง 'zlib'; ทำให้ Zlib.inflate (Base64.decode64 ( "eJxlkMEOwiAQRO98hekFuGzxQEwPXvwR01ZqiYHqBk2Tln8XDlWgnDbM25nJonq9NaoD7ZTtR9PigxK09zM7AkgRHieXTYHOsBNf1nklM6B6TuhYpdp + rPgSdiCOi / d / kQ71QBOtAVFLEDly05 + + UYQ2H MckL6z0zioDdJG1S9K1K4iQAW66DhnmiqRYKEJFXMByux + XuOJ2XdO60dKsjC7aBtyTL5O5hLk ="))
Chinoto Vokro

คำถามหนึ่งมันจะรักษาความแม่นยำเหมือนที่เราใช้ 'ทศนิยม' หรือไม่
อดัมไอเคน

39

คุณสามารถตรวจสอบได้ด้วย IRB:

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

26

คุณสามารถรวมmathnโมดูลทับทิม

require 'mathn'

ด้วยวิธีนี้คุณจะสามารถทำการแบ่งได้ตามปกติ

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

วิธีนี้คุณจะได้รับส่วนที่แน่นอน (ชั้น Rational) Math.sinจนกว่าคุณจะตัดสินใจที่จะใช้ดำเนินการที่ไม่สามารถแสดงเป็นเหตุผลที่ยกตัวอย่างเช่น


1
โมดูล mathn เลิกใช้แล้วตั้งแต่ ruby ​​2.2
Meier


6

Fixnum # to_r ไม่ได้กล่าวถึงที่นี่มันถูกนำมาใช้ตั้งแต่ทับทิม 1.9 มันแปลง Fixnum เป็นรูปแบบที่มีเหตุผล ด้านล่างนี้เป็นตัวอย่างการใช้งาน สิ่งนี้ยังสามารถแบ่งส่วนที่แน่นอนได้ตราบใดที่ตัวเลขทั้งหมดที่ใช้คือ 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

ตัวอย่างที่การดำเนินการลอยตัวบนจำนวนตรรกยะคลุมผลลัพธ์ที่จะลอย

a = 5.to_r   #=> (5/1) 
a = a * 5.0  #=> 25.0 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.