¿Por qué la división se redondea a un número entero? [duplicar]
Estaba tratando de normalizar un conjunto de números de -100 a 0 en un rango de 10-100 y tuve problemas solo para darme cuenta de que incluso sin ninguna variable, esto no evalúa la forma en que esperaría que lo hiciera:
>>> (20-10) / (100-10)
0
La división flotante tampoco funciona:
>>> float((20-10) / (100-10))
0.0
Si cualquiera de los lados de la división se convierte en un flotador, funcionará:
>>> (20-10) / float((100-10))
0.1111111111111111
Cada lado en el primer ejemplo se evalúa como un int, lo que significa que la respuesta final se convertirá en un int. Dado que 0,111 es menor que 0,5, se redondea a 0. En mi opinión, no es transparente, pero supongo que así es.
¿Cuál es la explicación?
Estás usando Python 2.x, donde las divisiones enteras se truncarán en lugar de convertirse en un número de punto flotante.
>>> 1 / 2
0
Deberías hacer que uno de ellos sea float
:
>>> float(10 - 20) / (100 - 10)
-0.1111111111111111
o from __future__ import division
, que obliga /
a adoptar el comportamiento de Python 3.x que siempre devuelve un valor flotante.
>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111
Estás poniendo números enteros para que Python te devuelva un número entero :
>>> 10 / 90
0
Si luego convierte esto en flotante, el redondeo ya se habrá realizado, en otras palabras, 0 entero siempre se convertirá en 0 flotante.
Si usa puntos flotantes a ambos lados de la división, Python le dará la respuesta que espera.
>>> 10 / 90.0
0.1111111111111111
Entonces en tu caso:
>>> float(20-10) / (100-10)
0.1111111111111111
>>> (20-10) / float(100-10)
0.1111111111111111
En Python 2.7, el /
operador es una división de números enteros si las entradas son números enteros:
>>>20/15
1
>>>20.0/15.0
1.33333333333
>>>20.0/15
1.33333333333
En Python 3.3, el /
operador es una división flotante incluso si las entradas son enteras.
>>> 20/15
1.33333333333
>>>20.0/15
1.33333333333
Para la división de enteros en Python 3, usaremos el //
operador.
El //
operador es un operador de división de enteros tanto en Python 2.7 como en Python 3.3.
En Python 2.7 y Python 3.3:
>>>20//15
1
Ahora, mira la comparación.
>>>a = 7.0/4.0
>>>b = 7/4
>>>print a == b
Para el programa anterior, el resultado será Falso en Python 2.7 y Verdadero en Python 3.3.
En Python 2.7 a = 1,75 y b = 1.
En Python 3.3 a = 1,75 y b = 1,75, simplemente porque /
es una división flotante.
Debes cambiarlo a flotante ANTES de hacer la división. Eso es:
float(20 - 10) / (100 - 10)
Tiene que ver con la versión de Python que utilizas. Básicamente adopta el comportamiento de C: si divides dos números enteros, los resultados se redondearán a la baja a un número entero. También tenga en cuenta que Python realiza las operaciones de izquierda a derecha, lo que influye al encasillar.
Ejemplo: dado que esta es una pregunta que siempre me viene a la cabeza cuando hago operaciones aritméticas (debo convertir a flotante y qué número), se presenta un ejemplo de ese aspecto:
>>> a = 1/2/3/4/5/4/3
>>> a
0
Cuando dividimos números enteros, no es sorprendente que se redondee hacia abajo.
>>> a = 1/2/3/4/5/4/float(3)
>>> a
0.0
Si encasillamos el último número entero para que flote, aún obtendremos cero, ya que cuando nuestro número se divide por el flotante ya se ha convertido en 0 debido a la división del entero.
>>> a = 1/2/3/float(4)/5/4/3
>>> a
0.0
El mismo escenario que el anterior pero desplazando el encasillado flotante un poco más hacia el lado izquierdo.
>>> a = float(1)/2/3/4/5/4/3
>>> a
0.0006944444444444445
Finalmente, cuando encasillamos el primer entero para que flote, el resultado es el deseado, ya que a partir de la primera división, es decir, la que está más a la izquierda, usamos flotantes.
Extra 1: si estás intentando responder eso para mejorar la evaluación aritmética, debes marcar esto
Extra 2: tenga cuidado con el siguiente escenario:
>>> a = float(1/2/3/4/5/4/3)
>>> a
0.0