Bagaimana saya bisa memaksa pembagian menjadi titik mengambang? Divisi terus membulatkan ke 0?

721

Saya memiliki dua nilai integer adan b, tetapi saya perlu rasio mereka di floating point. Saya tahu itu a < bdan saya ingin menghitung a / b, jadi jika saya menggunakan divisi integer saya akan selalu mendapatkan 0 dengan sisa a.

Bagaimana saya bisa memaksa cuntuk menjadi nomor floating point di Python di berikut ini?

c = a / b
Nathan Fellman
sumber
Tingkatkan saja ke Python 3.
Boris

Jawaban:

807

Dalam Python 2, pembagian dua int menghasilkan int. Dalam Python 3, ini menghasilkan pelampung. Kita bisa mendapatkan perilaku baru dengan mengimpor dari __future__.

>>> from __future__ import division
>>> a = 4
>>> b = 6
>>> c = a / b
>>> c
0.66666666666666663
Michael Fairley
sumber
13
Catatan yang from __future__ import divisionharus di bagian paling awal file
yannis
Juga masalahnya adalah jika Anda ingin divisi integer di satu tempat tetapi divisi float di tempat lain dari file ...
mercury0114
1
@ mercury0114: Tidak masalah; Anda hanya menggunakan //ketika Anda ingin pembagian lantai, dan /ketika Anda ingin floatdivisi "true" ( ).
ShadowRanger
715

Anda dapat melemparkan untuk mengapung dengan melakukan c = a / float(b). Jika pembilang atau penyebutnya adalah float, maka hasilnya juga akan menjadi.


Peringatan: seperti yang ditunjukkan oleh komentator, ini tidak akan berhasil jika bmungkin bukan angka integer atau floating-point (atau string yang mewakili satu). Jika Anda mungkin berurusan dengan tipe lain (seperti bilangan kompleks) Anda harus memeriksa atau menggunakan metode yang berbeda.

Steve Trout
sumber
195

Bagaimana saya bisa memaksa pembagian menjadi titik mengambang di Python?

Saya memiliki dua nilai integer a dan b, tetapi saya perlu rasio mereka di floating point. Saya tahu bahwa <b dan saya ingin menghitung a / b, jadi jika saya menggunakan divisi integer saya akan selalu mendapatkan 0 dengan sisa a.

Bagaimana saya bisa memaksa c menjadi angka floating point dalam Python di berikut ini?

c = a / b

Apa yang sebenarnya ditanyakan di sini adalah:

"Bagaimana saya memaksa pembagian yang benar sehingga a / bakan menghasilkan sebagian kecil?"

Tingkatkan ke Python 3

Di Python 3, untuk mendapatkan pembagian yang benar, Anda cukup melakukannya a / b.

>>> 1/2
0.5

Divisi lantai, perilaku divisi klasik untuk bilangan bulat, sekarang a // b:

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

Namun, Anda mungkin terjebak menggunakan Python 2, atau Anda mungkin menulis kode yang harus bekerja di kedua 2 dan 3.

Jika Menggunakan Python 2

Dalam Python 2, ini tidak sesederhana itu. Beberapa cara berurusan dengan divisi Python 2 klasik lebih baik dan lebih kuat daripada yang lain.

Rekomendasi untuk Python 2

Anda bisa mendapatkan perilaku divisi Python 3 di modul mana pun dengan impor berikut di atas:

from __future__ import division

yang kemudian menerapkan pembagian gaya Python 3 ke seluruh modul. Ia juga bekerja di shell python pada titik tertentu. Dengan Python 2:

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

Ini benar-benar solusi terbaik karena memastikan kode di modul Anda lebih maju kompatibel dengan Python 3.

Opsi lain untuk Python 2

Jika Anda tidak ingin menerapkan ini ke seluruh modul, Anda terbatas pada beberapa solusi. Yang paling populer adalah memaksa salah satu operan ke float. Salah satu solusi tangguh adalah a / (b * 1.0). Dalam kulit Python segar:

>>> 1/(2 * 1.0)
0.5

Juga kuat truedivdari operatormodul operator.truediv(a, b), tetapi ini kemungkinan lebih lambat karena itu adalah panggilan fungsi:

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

Tidak Direkomendasikan untuk Python 2

Yang biasa dilihat adalah a / float(b). Ini akan menaikkan TypeError jika b adalah bilangan kompleks. Karena pembagian dengan bilangan kompleks didefinisikan, masuk akal bagi saya untuk tidak mengalami kegagalan pembagian ketika melewati bilangan kompleks untuk pembagi.

>>> 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

Tidak masuk akal bagi saya untuk sengaja membuat kode Anda lebih rapuh.

Anda juga dapat menjalankan Python dengan -Qnewflag, tetapi ini memiliki kelemahan menjalankan semua modul dengan perilaku Python 3 yang baru, dan beberapa modul Anda mungkin mengharapkan pembagian klasik, jadi saya tidak merekomendasikan ini kecuali untuk pengujian. Tetapi untuk menunjukkan:

$ python -Qnew -c 'print 1/2'
0.5
$ python -Qnew -c 'print 1/2j'
-0.5j
Aaron Hall
sumber
3
"1 // 2 = 0", "1 // 2.0 = 0.0" - Gotcha kecil yang menarik, bahkan jika itu adalah divisi integer, jika salah satu operan mengambang maka hasilnya adalah bilangan bulat tetapi juga mengambang. Saya menggunakan divisi integer untuk menghitung indeks daftar dan mendapatkan kesalahan karena itu.
R. Navega
134
c = a / (b * 1.0)
Pinochle
sumber
66

Dalam Python 3.x, slash tunggal ( /) selalu berarti pembagian true (non-truncating). ( //Operator digunakan untuk memotong divisi.) Dalam Python 2.x (2.2 dan di atas), Anda bisa mendapatkan perilaku yang sama dengan meletakkan

from __future__ import division

di bagian atas modul Anda.

berita baru
sumber
30

Hanya membuat salah satu parameter untuk pembagian dalam format floating-point juga menghasilkan output dalam floating-point.

Contoh:

>>> 4.0/3
1.3333333333333333

atau,

>>> 4 / 3.0
1.3333333333333333

atau,

>>> 4 / float(3)
1.3333333333333333

atau,

>>> float(4) / 3
1.3333333333333333
gsbabil
sumber
4
Tetapi nanti Anda mungkin tergoda untuk melakukan 1.0 + 1/3atau float(c) + a/batau float(a/b)dan Anda akan kecewa dengan jawabannya. Lebih baik menggunakan python 3+ atau mengimpor __future__.divisionmodul, (lihat jawaban yang diterima), untuk selalu mendapatkan jawaban yang Anda harapkan. Aturan pembagian yang ada membuat kesalahan matematika yang sulit dilacak.
hobs
@ JoCondron Apakah Anda sudah mencoba python -c 'a=10; b=3.0; print a/b'?
gsbabil
Saya tidak perlu karena itu jelas berfungsi dalam skenario ini. Namun, bagaimana jika adan 'b', misalnya, apakah output dari fungsi nilai integer? Misalnya a = len(list1), b = len(list2),.
JoeCondron
@ JoCondron: poin bagus. Saya baru saja memperbarui jawaban untuk dimasukkan float(..). Saya pikir mengalikan dengan 1.0, seperti yang disarankan @Pinochle di bawah ini, juga bisa bermanfaat.
gsbabil
21

Tambahkan titik ( .) untuk menunjukkan angka floating point

>>> 4/3.
1.3333333333333333
Alexander
sumber
2
Bagaimana Anda akan menerapkan pendekatan ini jika pembilang dan penyebut keduanya variabel?
stackoverflowuser2010
Saya berasumsi Anda merujuk pada contoh pertama, jika demikian, saya hanya akan menggunakan float()salah satu variabel.
Alexander
13

Ini juga akan berfungsi

>>> u=1./5
>>> print u
0.2
Gaurav Agarwal
sumber
4
Dan bagaimana Anda akan menerapkan pendekatan ini jika pembilang dan penyebut keduanya variabel?
stackoverflowuser2010
1
Karena itu tidak berfungsi ketika variabel digunakan untuk abstraksi. Hampir tidak ada kode yang berarti memiliki nilai yang di-hardcode seperti itu.
Keir Simmons
1
Ini memiliki sedikit suara karena jawaban ini tidak menjawab pertanyaan, dan sama sekali bukan jawaban umum. Dalam jawaban, penting juga untuk menunjukkan mengapa ini berhasil. Ini sangat sederhana: jika pembilang atau penyebutnya adalah float, hasilnya adalah float. Biasanya Anda tidak menggunakan python sebagai kalkulator plaintext, jadi Anda ingin jawaban untuk variabel adan b.
TimZaman
Untuk waktu yang lama, saya benar-benar berpikir ./adalah operator yang sah dalam python yang memungkinkan Anda untuk melakukan pembagian floating point. Inilah sebabnya mengapa baik menggunakan ruang kosong secara bijaksana, dalam bahasa pemrograman apa pun
smac89
6

Jika Anda ingin menggunakan divisi "true" (floating point) secara default, ada flag baris perintah:

python -Q new foo.py

Ada beberapa kekurangan (dari PEP):

Telah dikemukakan bahwa opsi baris perintah untuk mengubah default adalah jahat. Ini tentu bisa berbahaya di tangan yang salah: misalnya, tidak mungkin untuk menggabungkan paket perpustakaan pihak ke-3 yang membutuhkan -Baru dengan yang lain yang membutuhkan -Qold.

Anda dapat mempelajari lebih lanjut tentang nilai-nilai flag lainnya yang mengubah / memperingatkan-tentang perilaku pembagian dengan melihat halaman python man.

Untuk detail lengkap tentang perubahan divisi, baca: PEP 238 - Mengubah Operator Divisi

stephenbez
sumber
2
from operator import truediv

c = truediv(a, b)
JoeCondron
sumber
2
Itu tidak ideal, karena itu tidak berfungsi dalam kasus di mana aint dan bfloat. Solusi yang lebih baik di sepanjang garis yang sama adalah melakukan from operator import truedivdan kemudian menggunakan truediv(a, b).
Mark Dickinson
Ya kamu benar. Saya berasumsi kedua bilangan bulat karena ini adalah satu-satunya waktu ketika ops divisi berbeda tetapi Anda benar-benar menginginkan solusi umum. Saya sebenarnya tidak tahu Anda bisa mengimpor operator atau itu tidak berfungsi sama sekali untuk pembagi float. Jawaban diedit.
JoeCondron
1
from operator import truediv

c = truediv(a, b)

di mana a adalah dividen dan b adalah pembagi. Fungsi ini berguna ketika hasil bagi setelah pembagian dua bilangan bulat adalah pelampung.

Chetan Yeshi
sumber