Come posso forzare la divisione in virgola mobile? La divisione continua ad arrotondare per difetto a 0?


721

Ho due valori interi ae b, ma ho bisogno del loro rapporto in virgola mobile. Lo so a < be voglio calcolare a / b, quindi se uso la divisione intera otterrò sempre 0 con il resto di a.

Come posso forzare cad essere un numero in virgola mobile in Python nel seguito?

c = a / b

Basta aggiornare a Python 3.
Boris,

Risposte:


807

In Python 2, la divisione di due ints produce un int. In Python 3, produce un float. Possiamo ottenere il nuovo comportamento importando da __future__.

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

13
Nota che from __future__ import divisiondeve essere all'inizio del file
yannis

Inoltre il problema è se si desidera la divisione intera in un posto ma la divisione float in un altro posto del file ...
mercury0114

1
@ mercury0114: non è un problema; si usa solo //quando si desidera la divisione del pavimento e /quando si desidera la floatdivisione "true" ( ).
ShadowRanger

715

Puoi lanciare per galleggiare facendo c = a / float(b). Se il numeratore o denominatore è un float, anche il risultato sarà.


Un avvertimento: come hanno sottolineato i commentatori, questo non funzionerà se bpotrebbe essere qualcosa di diverso da un numero intero o in virgola mobile (o una stringa che rappresenta uno). Se potresti avere a che fare con altri tipi (come numeri complessi), dovrai controllarli o utilizzare un metodo diverso.


195

Come posso forzare la divisione in virgola mobile in Python?

Ho due valori interi aeb, ma ho bisogno del loro rapporto in virgola mobile. So che a <b e voglio calcolare a / b, quindi se uso la divisione intera otterrò sempre 0 con il resto di a.

Come posso forzare c ad essere un numero in virgola mobile in Python nel seguito?

c = a / b

Ciò che viene veramente chiesto qui è:

"Come posso forzare la vera divisione in modo tale a / b restituire una frazione?"

Esegui l'upgrade a Python 3

In Python 3, per ottenere la vera divisione, lo fai semplicemente a / b.

>>> 1/2
0.5

La divisione dei piani, il classico comportamento di divisione per gli interi, è ora a // b:

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

Tuttavia, potresti essere bloccato usando Python 2 o potresti scrivere codice che deve funzionare sia in 2 che in 3.

Se si utilizza Python 2

In Python 2, non è così semplice. Alcuni modi di gestire la classica divisione Python 2 sono migliori e più robusti di altri.

Raccomandazione per Python 2

È possibile ottenere il comportamento della divisione Python 3 in un determinato modulo con la seguente importazione in alto:

from __future__ import division

che quindi applica la divisione di stile Python 3 all'intero modulo. Funziona anche in una shell Python in un dato punto. In Python 2:

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

Questa è davvero la soluzione migliore in quanto garantisce che il codice nel modulo sia più compatibile con Python 3.

Altre opzioni per Python 2

Se non si desidera applicare questo all'intero modulo, si è limitati ad alcune soluzioni alternative. Il più popolare è di forzare uno degli operandi su un float. Una soluzione solida è a / (b * 1.0). In una nuova shell Python:

>>> 1/(2 * 1.0)
0.5

Anche robusto è truedivdal operatormodulo operator.truediv(a, b), ma questo è probabilmente più lento perché è una chiamata di funzione:

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

Non consigliato per Python 2

Comunemente visto a / float(b). Ciò genererà un errore di tipo se b è un numero complesso. Dato che la divisione con numeri complessi è definita, per me ha senso non fallire la divisione quando viene passato un numero complesso per il divisore.

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

Non ha molto senso per me rendere intenzionalmente il tuo codice più fragile.

Puoi anche eseguire Python con il -Qnewflag, ma questo ha il rovescio della medaglia di eseguire tutti i moduli con il nuovo comportamento di Python 3 e alcuni dei tuoi moduli potrebbero aspettarsi una divisione classica, quindi non lo consiglio tranne per i test. Ma per dimostrare:

$ 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" - piccolo gotcha interessante, anche se è una divisione intera, se uno qualsiasi degli operandi è float, il risultato è un numero intero ma anche float. Stavo usando una divisione intera per calcolare un indice di elenco e ho ricevuto un errore a causa di ciò.
R. Navega,


66

In Python 3.x, la singola barra ( /) significa sempre vera divisione (non troncante). (L' //operatore viene utilizzato per troncare la divisione.) In Python 2.x (2.2 e versioni successive), è possibile ottenere lo stesso comportamento inserendo un

from __future__ import division

nella parte superiore del modulo.


30

La semplice creazione di uno qualsiasi dei parametri per la divisione in formato a virgola mobile produce anche l'output in virgola mobile.

Esempio:

>>> 4.0/3
1.3333333333333333

o,

>>> 4 / 3.0
1.3333333333333333

o,

>>> 4 / float(3)
1.3333333333333333

o,

>>> float(4) / 3
1.3333333333333333

4
Ma potresti in seguito essere tentato di fare 1.0 + 1/3o float(c) + a/bo float(a/b)e rimarrai deluso dalla risposta. Meglio usare python 3+ o importare il __future__.divisionmodulo, (vedi risposta accettata), per ottenere sempre la risposta che ti aspetti. Le regole di divisione esistenti creano errori matematici insidiosi e difficili da rintracciare.
Piani cottura

@JoeCondron Hai provato python -c 'a=10; b=3.0; print a/b'?
gsbabil,

Non dovevo farlo perché ovviamente funziona in questo scenario. Tuttavia, cosa succede se ae 'b', ad esempio, sono gli output di una funzione a valore intero? Ad es a = len(list1), b = len(list2).
JoeCondron,

@JoeCondron: buon punto. Ho appena aggiornato la risposta da includere float(..). Penso che anche moltiplicare 1.0, come suggerito da @Pinochle di seguito, potrebbe essere utile.
gsbabil,

21

Aggiungi un punto ( .) per indicare i numeri in virgola mobile

>>> 4/3.
1.3333333333333333

2
Come applicherai questo approccio se il numeratore e il denominatore sono entrambe variabili?
stackoverflowuser2010

Presumo che ti riferisca al primo esempio, se è così, lo userei solo float()su una delle variabili.
Alexander,

13

Questo funzionerà anche

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

4
E come applicherai questo approccio se il numeratore e il denominatore sono entrambe variabili?
stackoverflowuser2010

1
Perché non funziona quando le variabili vengono utilizzate per l'astrazione. Quasi nessun codice significativo ha valori codificati in questo modo.
Keir Simmons

1
Questo ha pochi voti perché questa risposta non risponde alla domanda e non è affatto una risposta generale. In una risposta è anche importante prima mostrare perché funziona. È molto semplice: se il numeratore o denominatore è un float, il risultato sarà un float. Di solito non usi Python come una calcolatrice in chiaro, quindi vuoi una risposta per variabili ae b.
TimZaman,

Per il tempo più lungo, in realtà ho pensato che ./fosse un valido operatore in Python che ti consentisse di eseguire la divisione in virgola mobile. Ecco perché è bene usare gli spazi bianchi in modo giudizioso, in qualsiasi linguaggio di programmazione
smac89

6

Se si desidera utilizzare la divisione "true" (virgola mobile) per impostazione predefinita, è presente un flag della riga di comando:

python -Q new foo.py

Ci sono alcuni svantaggi (dal PEP):

È stato sostenuto che un'opzione della riga di comando per modificare il valore predefinito è male. Può certamente essere pericoloso nelle mani sbagliate: ad esempio, sarebbe impossibile combinare un pacchetto di libreria di terze parti che richiede -Qnew con un altro che richiede -Qold.

Puoi saperne di più sugli altri valori di flag che cambiano / avvisano del comportamento della divisione guardando la pagina man di Python.

Per i dettagli completi sulle modifiche alla divisione, leggere: PEP 238 - Modifica dell'operatore divisione


2
from operator import truediv

c = truediv(a, b)

2
Questo non è l'ideale, tuttavia, poiché non funziona nel caso in cui aè un int ed bè un float. Una soluzione migliore sulla stessa linea è fare from operator import truedive poi usare truediv(a, b).
Mark Dickinson,

Si hai ragione. Stavo assumendo entrambi i numeri interi poiché questa è l'unica volta in cui le operazioni di divisione differiscono ma tu vuoi davvero una soluzione generale. In realtà non sapevo che potresti importare l'operatore o che non funziona affatto per i divisori float. Risposta modificata.
JoeCondron,

1
from operator import truediv

c = truediv(a, b)

dove a è dividendo eb è il divisore. Questa funzione è utile quando il quoziente dopo la divisione di due numeri interi è un float.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.