Чому поділ у Ruby повертає ціле число замість десяткового значення?


256

Наприклад:

9 / 5  #=> 1

але я очікував 1.8. Як я можу отримати правильний десятковий (не цілий) результат? Чому воно взагалі повертається 1?


4
Зауважте, що якщо ви фактично використовуєте метод для повернення цього значення, вам не потрібно призначати його змінній; просто def method; a - b/8; endповертає результат обчислення з методу, оскільки останнім виразом у виклику методу є повернене значення.
Фрогз

Відповіді:


268

Це робить ціле ділення. Ви можете зробити одне з чисел a Float, додавши .0:

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

10
Це працює, але відповідь to_f нижче здається більш корисною. Чи то_fio ідіоматичніший у Рубі?
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
Це швидше відповідь «рейки», ніж прийнята відповідь.
Шон Райан

@muistooshort: я не можу його повторити, вибачте. Я, певно, робив щось не так.
Жоао Коста-

4
@SeanRyan Чому саме Rails, а не Рубі взагалі? Я не розумію, чому розробник (Ruby on) Rails зробив би цю конкретну справу інакше, ніж звичайний розробник Ruby. Можливо, я просто семантику, що зациклюється, і більшість людей просто сприймають (Ruby on) Rails і Ruby як синоніми у таких випадках.
Чіното Вокро

169

Існує також Numeric#fdivметод, який ви можете використовувати замість цього:

9.fdiv(5)  #=> 1.8

1
Це найшвидший метод, який я перевірив. Єдиний спосіб отримати більшу продуктивність - це ділити операнди, які починаються з поплавцями. Я створив генератор простих чисел в Ruby, щоб вивчити синтаксис, тепер я оптимізую його, щоб дізнатися, що найкраще працює. Ось тест я з'єднував: вимагають '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 є застарілим , так як рубін 2.2
Мейєра


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 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.