Podział liczb całkowitych w języku Python daje liczbę zmiennoprzecinkową

223
Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 2/2
1.0

Czy to jest zamierzone? Mocno pamiętam powracające wcześniejsze wersje int/int=int? Co powinienem zrobić, czy jest nowy operator działu, czy zawsze muszę go obsadzać?

Jonas Byström
źródło
31
Tak, tak działa podział w 3.x.
hughdbrown
2
Oto post twórcy Pythona mówiący o tym, jak działa zaokrąglanie, jest ortogonalny w stosunku do twojego pytania, ale uznałem, że jest interesujący: python-history.blogspot.com/2010/08/08/…
Aaron D
@hughdbrown, czyli zasadniczo dla wszystkich wersji Pythona 3?
Charlie Parker
@hughdbrown: tak, PEP jest ostateczny , co oznacza zarówno zaakceptowany, jak i wdrożony.
Jonas Byström

Odpowiedzi:

285

Spójrz na PEP-238 : Zmiana operatora dywizji

Operator // będzie mógł jednoznacznie zażądać podziału podłogi.

Brandon E. Taylor
źródło
10
@JathanathanSternberg z wyjątkiem całego kodu napisanego dla Pythona 2.0. Wydaje mi się, że rola / i // powinna zostać odwrócona, aby zachować kompatybilność wsteczną. Również w prawie każdym innym języku / typie zachowań. miałbym więcej sensu niż //, aby automatycznie przekonwertować na zmiennoprzecinkowe, a nie /.
thang
1
Druga część (po „również”) ma sens (podobieństwo do innych języków), ale jeśli chodzi o pierwszą część, cała kwestia Pythona 3 nie była zgodna z Pythonem 2, ale raczej naprawiła kilka problemów z Pythonem 2. Wystarczająco wielu ludzi uznało, że dwuznaczność /jest wystarczającą „błędą” projektu językowego, którą należało naprawić w Pythonie 3. Być może była to kontrowersyjna decyzja, ale wystarczająco wielu ludzi uważało, że była to poprawna decyzja. Policz mnie w grupie, która uwielbia zmianę. Fajnie, wszyscy możemy się zgodzić, że się nie zgodzimy. Twoje zdrowie. :)
Ray Toal,
59

Ups, natychmiast znaleziono 2//2.

Jonas Byström
źródło
5
Czy mógłbyś opracować?
blueFast
4
Użycie tego spowoduje wygenerowanie int, a nie liczby zmiennoprzecinkowej @dangonfast.
Ashish Ahuja
To wydaje się nie działać dla liczb ujemnych. -1 // 5 zwraca -1, a -5 // 5 zwraca -1.
mschuett
@mschuett: należy się tego spodziewać i jest to ten sam wynik, co w przypadku Pythona 2.
Jonas Byström
1
Tak, jeszcze trochę kopałem i to odkryłem. Wyobrażam sobie jednak, że spora liczba osób nie zdaje sobie z tego sprawy, w zależności od języka, z którego pochodzą.
mschuett
45

Mam nadzieję, że może to komuś pomóc natychmiast.

Zachowanie operatora podziału w Python 2.7 i Python 3

W Pythonie 2.7: domyślnie operator dzielenia zwraca wartość całkowitą.

aby uzyskać wynik podwójnej wielokrotności 1.0 do „dywidendy lub dzielnika”

100/35 => 2 #(Expected is 2.857142857142857)
(100*1.0)/35 => 2.857142857142857
100/(35*1.0) => 2.857142857142857

W Python 3

// => used for integer output
/ => used for double output

100/35 => 2.857142857142857
100//35 => 2
100.//35 => 2.0    # floating-point result if divsor or dividend real
VijayNaidu
źródło
1
Nawiasem mówiąc, nie ma potrzeby mnożenia przez 1,0. Wystarczy, że jedna z liczb jest liczbą zmiennoprzecinkową. Np. 100 / 35,0 = 100,0 / 35 = 2,857142857142857
Tal J. Levy
21

W przyjętej odpowiedzi wspomniano już o PEP 238 . Chcę tylko rzucić okiem na kulisy tych, którzy są zainteresowani tym, co się dzieje, bez czytania całego PEP.

Python mapy operatorów jak +, -, *i /do specjalnych funkcji, tak, że na przykład a + bjest równoważny

a.__add__(b)

Jeśli chodzi o podział Pythona 2 jest jedynie domyślnie /które odwzorowuje się __div__, a wynik zależy od rodzaju surowców (np int, float).

Python 2.2 wprowadził tę __future__funkcję division, która zmieniła semantykę podziału w następujący sposób (TL; DR PEP 238):

  • /mapy, do __truediv__których musi „zwrócić rozsądne przybliżenie matematycznego wyniku podziału” (cytat z PEP 238)
  • //odwzorowuje na __floordiv__, co powinno zwrócić wynik zmienny z/

W Pythonie 3.0 zmiany PEP 238 stały się zachowaniem domyślnym i nie ma już specjalnej metody __div__w modelu obiektowym Pythona.

Jeśli chcesz użyć tego samego kodu w Python 2 i Python 3 użyj

from __future__ import division

i trzymaj się semantyki PEP 238 /i //.

code_onkel
źródło
0

Zgodnie z dokumentacją Python3, python po podzieleniu przez liczbę całkowitą wygeneruje liczbę zmiennoprzecinkową, mimo że oczekuje się, że będzie liczbą całkowitą.

Do drukowania wyłącznie liczb całkowitych użyj floor division method. Podział podłogi zaokrągla zero i usuwa przecinek dziesiętny.Represented by //

Dlatego zamiast 2/2 użyj 2//2

Możesz także zaimportować podział __future__niezależnie od używania python2 lub python3.

Mam nadzieję, że to pomoże!

addy
źródło