2012-02-17 14 views
6

Eksperymentowałem z możliwościami matematycznymi Pythona i natrafiłem na ciekawe zachowanie. Jest to związane z następującym wyrażeniem:Dlaczego Python nieprawidłowo ocenia to wyrażenie?

(4+4)+3/4/5*35-(3*(5+7))-6+434+5+5+5 

>>> 415 

Jednakże, jeśli ocena ekspresji ze standardowej kolejności operacji na uwadze, odpowiedź powinna być 420.25. Sprawdziłem również dwukrotnie z WolframAlpha, co daje odpowiedź 420,25. Dlaczego Python podaje inną odpowiedź? Czy ma to coś wspólnego z tym, jak ocenia takie wyrażenia? Czy jest jakaś konwencja, która się podąża? Wszelkie informacje będą bardzo mile widziane, dzięki!

+0

Domyślam się, że jeśli znajdzie '3/4/5 * 35' niejednoznaczne i ocenia to inaczej niż ty. Najlepiej umieścić niektóre nawiasy w tym języku. – inspectorG4dget

+0

Zasady pierwszeństwa w języku programowania mogą nie być iw tym przypadku nie są dokładnie takie same jak w zwykłej matematyce. również w zwykłej matematyce, której ekspresja wynosi około 415.00428571428574 – ChessMaster

+0

Czy próbowałeś tworzyć prostsze przykłady? –

Odpowiedz

10

Chcesz użyć zmiennoprzecinkowych podział. Zmiana do tego działa:

(4+4)+3.0/4/5*35-(3*(5+7))-6+434+5+5+5 

Przykłady całkowitej podziału porównaniu zmiennoprzecinkowej podziału:

Python 2.7.2+ (default, Oct 4 2011, 20:06:09) 
>>> 3/4 
0 
>>> 3.0/4 
0.75 
>>> 3.0/4.0 
0.75 

Pływak podzielona przez liczbę całkowitą jest operacja zmiennoprzecinkową. Python 3 nie zmieniło to tak, że zmiennoprzecinkową podział jest domyślnie:

Python 3.2.2 (default, Sep 5 2011, 21:17:14) 
>>> 3/4 
0.75 
4

W Pythonie 2.x/użytkownik całkowitą podział. Jeśli napiszesz

(4+4)+3.0/4.0/5.0*35-(3*(5+7))-6+434+5+5+5 

to da oczekiwaną odpowiedź.

4

To zależy od wersji Pythona używasz:

$ python3 
Python 3.1.4 (default, Nov 12 2011, 12:16:31) 
[GCC 4.4.5] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> (4+4)+3/4/5*35-(3*(5+7))-6+434+5+5+5 
420.25 

Przed Pythonie 3, operator / wykonano całkowitą podział zamiast zmiennoprzecinkowej.

7

Ponieważ w Pythonie 2 / wykorzystuje podział całkowitej gdy operatora i argumentu operacji są liczbami całkowitymi.

Można też zmienić jeden z pływakiem (jak inne Główni odpowiadający zasugerowali), lub użyć from __future__ import division: http://www.python.org/dev/peps/pep-0238/

3

To całkowitą podział. W twoim przykładzie wartość 3/4 jest równa 0. Jednak wartość 3.0/4.0 wynosi 0,75.

>>> (4+4)+3/4/5*35-(3*(5+7))-6+434+5+5+5 
415 
>>> (4+4)+3./4/5*35-(3*(5+7))-6+434+5+5+5 
420.25 

To zachowanie zostało zmienione w Pythonie w wersjach 3 i nowszych. Jeśli chcesz, aby był domyślny podział na zmiennoprzecinkowe, możesz zaimportować regułę.

>>> from __future__ import division 
>>> (4+4)+3/4/5*35-(3*(5+7))-6+434+5+5+5 
420.25 
1

ważne, aby zauważyć, że ani pyton lub WolframAlpha nie daje matematycznie właściwą odpowiedź, ponieważ w matematyce robimy mnożenie przed podziałem i Pythona * i/mają taki sam priorytet, więc oceni lewej do prawej.

3.0/4/5*35 # equal 5.25 in python 
3.0/4/5*35 # equal 3.0/4/(5*35) or 0.004285714285714286 in math 
Powiązane problemy