¿Cómo puedo forzar la división a ser punto flotante? División sigue redondeando a 0?

721

Tengo dos valores enteros ay b, pero necesito su relación en coma flotante. Lo sé a < by quiero calcular a / b, así que si uso la división de enteros siempre obtendré 0 con un resto de a.

¿Cómo puedo forzar ca ser un número de coma flotante en Python en lo siguiente?

c = a / b
Nathan Fellman
fuente
Simplemente actualice a Python 3.
Boris

Respuestas:

807

En Python 2, la división de dos entradas produce un int. En Python 3, produce un flotador. Podemos obtener el nuevo comportamiento importando desde __future__.

>>> from __future__ import division
>>> a = 4
>>> b = 6
>>> c = a / b
>>> c
0.66666666666666663
Michael Fairley
fuente
13
Tenga en cuenta que from __future__ import divisiondebe estar al comienzo del archivo
yannis
También el problema es que si quieres la división entera en un solo lugar, pero la división de flotación en otro lugar del archivo ...
mercury0114
1
@ mercury0114: No es un problema; solo se usa //cuando se desea la división de piso y /cuando se desea la floatdivisión "verdadera" ( ).
ShadowRanger
715

Puedes lanzar para flotar haciendo c = a / float(b). Si el numerador o denominador es flotante, el resultado también lo será.


Una advertencia: como han señalado los comentaristas, esto no funcionará si bpodría ser algo más que un número entero o de coma flotante (o una cadena que representa uno). Si puede estar tratando con otros tipos (como números complejos), deberá verificarlos o utilizar un método diferente.

Trucha Steve
fuente
195

¿Cómo puedo forzar la división para que sea punto flotante en Python?

Tengo dos valores enteros a y b, pero necesito su relación en coma flotante. Sé que a <by quiero calcular a / b, así que si uso la división entera siempre obtendré 0 con el resto de a.

¿Cómo puedo forzar a c a ser un número de coma flotante en Python en lo siguiente?

c = a / b

Lo que realmente se pregunta aquí es:

"¿Cómo forzo una verdadera división tal que a / bdevuelva una fracción?"

Actualiza a Python 3

En Python 3, para obtener una verdadera división, simplemente hazlo a / b.

>>> 1/2
0.5

La división de piso, el comportamiento clásico de división para enteros, ahora es a // b:

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

Sin embargo, puede estar atascado usando Python 2, o puede estar escribiendo código que debe funcionar tanto en 2 como en 3.

Si usa Python 2

En Python 2, no es tan simple. Algunas formas de lidiar con la división clásica de Python 2 son mejores y más robustas que otras.

Recomendación para Python 2

Puede obtener el comportamiento de división de Python 3 en cualquier módulo dado con la siguiente importación en la parte superior:

from __future__ import division

que luego aplica la división de estilo Python 3 a todo el módulo. También funciona en un shell de python en cualquier punto dado. En Python 2:

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

Esta es realmente la mejor solución, ya que garantiza que el código en su módulo sea más compatible con Python 3.

Otras opciones para Python 2

Si no desea aplicar esto a todo el módulo, está limitado a algunas soluciones alternativas. Lo más popular es obligar a uno de los operandos a flotar. Una solución robusta es a / (b * 1.0). En una nueva carcasa de Python:

>>> 1/(2 * 1.0)
0.5

También es robusto truedivdel operatormódulo operator.truediv(a, b), pero es probable que sea más lento porque es una llamada de función:

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

No recomendado para Python 2

Comúnmente visto es a / float(b). Esto generará un TypeError si b es un número complejo. Como la división con números complejos está definida, tiene sentido para mí que no falle la división cuando se pasa un número complejo para el divisor.

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

No tiene mucho sentido para mí hacer que su código sea más frágil a propósito.

También puede ejecutar Python con el -Qnewindicador, pero esto tiene la desventaja de ejecutar todos los módulos con el nuevo comportamiento de Python 3, y algunos de sus módulos pueden esperar una división clásica, por lo que no recomiendo esto, excepto para las pruebas. Pero para demostrar:

$ python -Qnew -c 'print 1/2'
0.5
$ python -Qnew -c 'print 1/2j'
-0.5j
Aaron Hall
fuente
3
"1 // 2 = 0", "1 // 2.0 = 0.0": un pequeño problema interesante, incluso si se trata de una división entera, si alguno de los operandos es flotante, entonces el resultado es un número entero pero también flotante. Estaba usando una división entera para calcular un índice de lista y obtengo un error debido a eso.
R. Navega
134
c = a / (b * 1.0)
Pinochle
fuente
66

En Python 3.x, la barra simple ( /) siempre significa división verdadera (no truncada). (El //operador se usa para truncar la división). En Python 2.x (2.2 y superior), puede obtener este mismo comportamiento colocando un

from __future__ import division

en la parte superior de tu módulo.

newacct
fuente
30

Simplemente hacer que cualquiera de los parámetros para la división en formato de punto flotante también produzca la salida en punto flotante.

Ejemplo:

>>> 4.0/3
1.3333333333333333

o,

>>> 4 / 3.0
1.3333333333333333

o,

>>> 4 / float(3)
1.3333333333333333

o,

>>> float(4) / 3
1.3333333333333333
gsbabil
fuente
44
Pero es posible que más tarde sienta la tentación de hacer 1.0 + 1/3o float(c) + a/bo float(a/b)y se sentirá decepcionado con la respuesta. Es mejor usar python 3+ o importar el __future__.divisionmódulo (vea la respuesta aceptada) para obtener siempre la respuesta que espera. Las reglas de división existentes crean un error matemático insidioso y difícil de rastrear.
encimeras
@JoeCondron ¿Lo intentaste python -c 'a=10; b=3.0; print a/b'?
gsbabil
No tuve que hacerlo porque obviamente funciona en este escenario. Sin embargo, ¿qué sucede si ay 'b', por ejemplo, son las salidas de una función de valor entero? Ej a = len(list1), b = len(list2).
JoeCondron
@ JoeCondron: buen punto. Acabo de actualizar la respuesta para incluir float(..). Creo que multiplicar por 1.0, como @Pinochle sugirió a continuación, también podría ser útil.
gsbabil
21

Agregue un punto ( .) para indicar números de coma flotante

>>> 4/3.
1.3333333333333333
Alejandro
fuente
2
¿Cómo va a aplicar este enfoque si el numerador y el denominador son ambas variables?
stackoverflowuser2010
Supongo que se refiere al primer ejemplo, si es así, simplemente usaría float()una de las variables.
Alexander
13

Esto también funcionará

>>> u=1./5
>>> print u
0.2
Gaurav Agarwal
fuente
44
¿Y cómo va a aplicar este enfoque si el numerador y el denominador son ambas variables?
stackoverflowuser2010
1
Porque no funciona cuando se usan variables para la abstracción. Casi ningún código significativo tiene valores codificados de esa manera.
Keir Simmons
1
Esto tiene pocos votos porque esta respuesta no responde la pregunta, y no es una respuesta general en absoluto. En una respuesta, también es importante primero mostrar por qué esto funciona. Es muy simple: si el numerador o denominador es flotante, el resultado será flotante. Por lo general, no usa Python como una calculadora de texto sin formato, por lo que desea una respuesta para las variables ay b.
TimZaman
Durante mucho tiempo, en realidad pensé que ./era un operador válido en Python que le permite hacer la división de coma flotante. Es por eso que es bueno usar el espacio en blanco con prudencia, en cualquier lenguaje de programación
smac89
6

Si desea utilizar la división "verdadero" (punto flotante) de forma predeterminada, hay un indicador de línea de comando:

python -Q new foo.py

Hay algunos inconvenientes (del PEP):

Se ha argumentado que una opción de línea de comando para cambiar el valor predeterminado es mala. Ciertamente puede ser peligroso en las manos equivocadas: por ejemplo, sería imposible combinar un paquete de biblioteca de terceros que requiera -Qnew con otro que requiera -Qold.

Puede obtener más información sobre los otros valores de las banderas que cambian / advierten sobre el comportamiento de la división mirando la página del manual de Python.

Para más detalles sobre los cambios de división, lea: PEP 238 - Cambio del operador de división

stephenbez
fuente
2
from operator import truediv

c = truediv(a, b)
JoeCondron
fuente
2
Sin embargo, eso no es ideal, ya que no funciona en el caso de que asea ​​un int y bsea ​​un flotador. Una mejor solución en la misma línea es hacer from operator import truedivy luego usar truediv(a, b).
Mark Dickinson
Si, tienes razón. Estaba asumiendo ambos enteros, ya que este es el único momento en que las operaciones de división difieren, pero realmente quieres una solución general. En realidad, no sabía que podía importar el operador o que no funciona para los divisores flotantes. Respuesta editada.
JoeCondron
1
from operator import truediv

c = truediv(a, b)

donde a es dividendo y b es el divisor. Esta función es útil cuando el cociente después de la división de dos enteros es flotante.

Chetan Yeshi
fuente