Як я можу змусити поділ бути плаваючою точкою? Ділення продовжує округлення до 0?


721

У мене є два цілих значення aі b, але мені потрібно їх співвідношення у плаваючій точці. Я це знаю a < bі хочу обчислити a / b, тому якщо я буду використовувати ціле ділення, я завжди отримуватиму 0 із залишком a.

Як я можу змусити cбути числом з плаваючою комою в Python наступним чином?

c = a / b

Просто
Борис

Відповіді:


807

У Python 2 поділ двох int виробляє int. У Python 3 він виробляє поплавок. Ми можемо отримати нову поведінку, імпортуючи з __future__.

>>> from __future__ import division
>>> a = 4
>>> b = 6
>>> c = a / b
>>> c
0.66666666666666663

13
Зауважте, що це from __future__ import divisionмає бути на самому початку файлу
yannis

Також проблема полягає в тому, якщо ви хочете, щоб ціле ділення в одному місці, але поділ з плаваючою в іншому місці файлу ...
mercury0114

1
@ mercury0114: Не проблема; ви просто використовуєте, //коли ви хочете поділ підлоги, і /коли ви хочете "справжній" ( float) поділ.
ShadowRanger

715

Ви можете кинути плавати, роблячи c = a / float(b). Якщо чисельник чи знаменник - поплавок, то результат також буде.


Застереження: як зазначили коментатори, це не спрацює, якщо це bможе бути щось інше, ніж ціле число або число з плаваючою комою (або рядок, що представляє один). Якщо ви можете мати справу з іншими типами (наприклад, складними номерами), вам потрібно буде або перевірити їх, або скористатися іншим методом.


195

Як я можу змусити поділ бути плаваючою точкою в Python?

У мене є два цілих значення a і b, але мені потрібно їх співвідношення в плаваючій точці. Я знаю, що a <b, і я хочу обчислити a / b, тому якщо я буду використовувати ціле ділення, я завжди отримуватиму 0 з залишком a.

Як я можу змусити c бути числом з плаваючою комою в Python у наступному?

c = a / b

Що насправді тут задають:

"Як змусити справжній поділ таким, що a / bповерне дріб?"

Оновіть до Python 3

У Python 3, щоб отримати справжній поділ, ви просто зробите a / b.

>>> 1/2
0.5

Ділення підлоги, класичне поведінка ділення для цілих чисел, зараз a // b:

>>> 1//2
0
>>> 1//2.0
0.0

Однак ви можете застрягти за допомогою Python 2 або ви можете написати код, який повинен працювати як в 2, так і в 3.

Якщо використовується Python 2

У Python 2 це не так просто. Деякі способи поводження з класичним поділом Python 2 є кращими та надійнішими, ніж інші.

Рекомендація для Python 2

Ви можете отримати поведінку поділу Python 3 у будь-якому даному модулі із наступним імпортом у верхній частині:

from __future__ import division

який потім застосовує поділ стилю Python 3 до всього модуля. Він також працює в оболонці пітона в будь-якій заданій точці. У Python 2:

>>> from __future__ import division
>>> 1/2
0.5
>>> 1//2
0
>>> 1//2.0
0.0

Це дійсно найкраще рішення, оскільки воно забезпечує код у вашому модулі більш сумісним вперед із Python 3.

Інші параметри для Python 2

Якщо ви не хочете застосувати це до всього модуля, ви обмежені кількома способами обходу. Найпопулярнішим є примушування одного з операндів до поплавця. Одне надійне рішення a / (b * 1.0). У свіжкій оболонці Python:

>>> 1/(2 * 1.0)
0.5

Також надійний truedivвід operatorмодуля operator.truediv(a, b), але це, ймовірно, повільніше, оскільки це виклик функції:

>>> from operator import truediv
>>> truediv(1, 2)
0.5

Не рекомендується для Python 2

Поширеним є a / float(b). Це підніме TypeError, якщо b - комплексне число. Оскільки поділ зі складними числами визначено, для мене є сенсом не мати провал ділення при передачі складного числа дільнику.

>>> 1 / float(2)
0.5
>>> 1 / float(2j)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float

Для мене не має сенсу цілеспрямовано робити ваш код більш крихким.

Ви також можете запустити Python із -Qnewпрапором, але це має і зворотний бік виконання всіх модулів з новою поведінкою Python 3, і деякі ваші модулі можуть очікувати класичного поділу, тому я не рекомендую цього, крім тестування. Але продемонструвати:

$ python -Qnew -c 'print 1/2'
0.5
$ python -Qnew -c 'print 1/2j'
-0.5j

3
"1 // 2 = 0", "1 // 2.0 = 0.0" - маленький цікавий готч, навіть якщо це ціле ділення, якщо будь-який з операндів є плаваючим, то результат є цілим числом, але також плаває. Я використовував ціле ділення, щоб обчислити індекс списку і отримати помилку через це.
Р. Навега


66

У Python 3.x один проріз ( /) завжди означає істинний (не обрізаючий) поділ. ( //Оператор використовується для обрізання поділу.) У Python 2.x (2.2 і вище) ви можете отримати таку саму поведінку, поставивши

from __future__ import division

у верхній частині вашого модуля.


30

Виконання будь-якого з параметрів поділу у форматі з плаваючою комою також дає результат у плаваючій крапці.

Приклад:

>>> 4.0/3
1.3333333333333333

або,

>>> 4 / 3.0
1.3333333333333333

або,

>>> 4 / float(3)
1.3333333333333333

або,

>>> float(4) / 3
1.3333333333333333

4
Але ви могли б пізніше виникнути спокуса зробити 1.0 + 1/3або float(c) + a/bчи , float(a/b)і ви будете розчаровані з відповіддю. Краще використовувати python 3+ або імпортувати __future__.divisionмодуль (див. Прийняту відповідь), щоб завжди отримати відповідь, яку ви очікуєте. Існуючі правила поділу створюють підступну, важко відстежувану математичну помилку.
варильні панелі

@JoeCondron Ви пробували python -c 'a=10; b=3.0; print a/b'?
gsbabil

Мені цього не довелося, бо це очевидно працює за цим сценарієм. Однак що робити, якщо aі "b", наприклад, є виведеннями цілочислової функції? Наприклад, a = len(list1), b = len(list2).
JoeCondron

@JoeCondron: хороший момент. Я щойно оновив відповідь, щоб включити float(..). Я думаю, що множення на 1.0, як запропонував @Pinochle, також може бути корисним.
gsbabil

21

Додайте крапку ( .) для позначення чисел з плаваючою комою

>>> 4/3.
1.3333333333333333

2
Як ви будете застосовувати цей підхід, якщо чисельник та знаменник є обома змінними?
stackoverflowuser2010

Я припускаю, що ви посилаєтесь на перший приклад, якщо це так, я б просто скористався float()однією із змінних.
Олександр

13

Це також спрацює

>>> u=1./5
>>> print u
0.2

4
І як ви будете застосовувати такий підхід, якщо чисельник і знаменник є обома змінними?
stackoverflowuser2010

1
Тому що він не працює, коли змінні використовуються для абстрагування. Майже жоден змістовний код не має таких жорстких кодів.
Кейр Сіммонс

1
У цьому мало голосів, оскільки ця відповідь не відповідає на питання, і взагалі не є загальною відповіддю. У відповідь також важливо спочатку показати, чому це працює. Це дуже просто: якщо чисельник або знаменник є поплавком, результатом буде поплавок. Зазвичай ви не використовуєте python як калькулятор простого тексту, тому ви хочете відповісти для змінних aта b.
TimZaman

Протягом найдовшого часу я фактично думав, що ./це дійсний оператор у python, який дозволяє робити поділ з плаваючою комою. Ось чому добре використовувати пробіл розумно, будь-якою мовою програмування
smac89

6

Якщо ви хочете використовувати розділення "true" (плаваюча точка) за замовчуванням, є прапор командного рядка:

python -Q new foo.py

Є деякі недоліки (від PEP):

Стверджувалося, що параметр командного рядка для зміни за замовчуванням є злим. Це може бути небезпечно в чужих руках: наприклад, неможливо було б поєднати пакет сторонніх бібліотек, який вимагає -Qnew з іншим, який вимагає -Qold.

Ви можете дізнатися більше про інші значення прапорців, які змінюються / попереджають - про поведінку поділу, переглянувши сторінку чоловіка python.

Повна інформація про зміни підрозділу читайте: PEP 238 - Зміна оператора відділу


2
from operator import truediv

c = truediv(a, b)

2
Це не ідеально, однак це не працює в тому випадку, коли aце int і bfloat. Краще рішення за тими ж напрямками - це зробити, from operator import truedivа потім використовувати truediv(a, b).
Марк Дікінсон

Так, ти маєш рацію. Я припускав обидва цілих числа, оскільки це єдиний час, коли ділення ops різняться, але ви дійсно хочете загального рішення. Я насправді не знав, що ви можете імпортувати оператора або що він взагалі не працює для плаваючих дільників. Відповідь відредаговано.
JoeCondron

1
from operator import truediv

c = truediv(a, b)

де a - дивіденд, а b - дільник. Ця функція зручна, коли коефіцієнт після ділення двох цілих чисел є поплавком.

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