libreria - ¿Por qué las operaciones math.ceil() y math.floor() de Python devuelven flotantes en lugar de enteros?
python 3.6 math module (8)
¿Alguien puede explicar esto (directamente desde los docs - énfasis mío):
math.ceil (x) Devuelve el techo de x como un flotante , el valor entero más pequeño mayor que o igual a x.
math.floor (x) Devuelve el piso de x como un flotante , el valor entero más grande menor o igual a x.
¿Por qué los .ceil
y .floor
devolverán flotantes cuando se supone que calculan enteros por definición?
EDITAR:
Bueno, esto tiene algunos muy buenos argumentos sobre por qué deberían devolver las carrozas, y me estaba acostumbrando a la idea, cuando @jcollado señaló que, de hecho , devuelven inyecciones en Python 3 ...
¡Esta es una pregunta muy interesante! Como un float requiere algunos bits para almacenar el exponente (= bits_for_exponent
), cualquier número de punto flotante mayor que 2**(float_size - bits_for_exponent)
siempre será un valor integral. En el otro extremo, un flotador con un exponente negativo dará uno de 1
, 0
o -1
. Esto hace que la discusión del rango entero frente al rango flotante sea discutible porque estas funciones simplemente devolverán el número original siempre que el número esté fuera del rango del tipo entero. Las funciones python son envoltorios de la función C
, por lo que esto es realmente una deficiencia de las funciones C
donde deberían haber devuelto un número entero y forzado al programador a hacer la comprobación de rango / NaN
/ Inf
antes de llamar a ceil / piso.
Por lo tanto, la respuesta lógica es la única vez que estas funciones son útiles, devuelven un valor dentro del rango entero y, por lo tanto, el hecho de que devuelvan un flotador es un error y usted es muy inteligente para darse cuenta de esto.
Antes de Python 2.4, un entero no podía contener el rango completo de números reales truncados.
http://docs.python.org/whatsnew/2.4.html#pep-237-unifying-long-integers-and-integers
Como se señala en otras respuestas, en Python devuelven flotadores probablemente debido a razones históricas para evitar problemas de desbordamiento. Sin embargo, devuelven enteros en python 3.
>>> import math
>>> type(math.floor(3.1))
<class ''int''>
>>> type(math.ceil(3.1))
<class ''int''>
Puede encontrar más información en PEP 3141 .
Debido a que el rango de flotantes es mayor que el de los enteros, devolver un entero podría desbordarse
Debido a que la biblioteca de matemáticas de Python es una envoltura delgada alrededor de la biblioteca matemática C, que devuelve flotantes.
El rango de números de coma flotante generalmente excede el rango de números enteros. Al devolver un valor de coma flotante, las funciones pueden devolver un valor razonable para los valores de entrada que se encuentran fuera del rango representable de los números enteros.
Considere: Si floor()
devolvió un número entero, ¿qué debería devolver el floor(1.0e30)
?
Ahora, aunque los enteros de Python son ahora de precisión arbitraria, no siempre fue así. Las funciones de biblioteca estándar son envoltorios delgados alrededor de las funciones de biblioteca C equivalentes.
La fuente de tu confusión es evidente en tu comentario:
¡El objetivo de las operaciones de cielorraso / piso es convertir flotadores en enteros!
El objetivo de las operaciones de cielorraso y piso es redondear los datos de coma flotante a valores integrales . No hacer una conversión de tipo. Los usuarios que necesitan obtener valores enteros pueden realizar una conversión explícita después de la operación.
Tenga en cuenta que no sería posible implementar una ronda de valor integral tan trivialmente si todo lo que tenía disponible fuera una operación de ceil o flotante que devolviera un número entero. Necesitaría verificar primero que la entrada está dentro del rango entero representable, luego llamar a la función; necesitaría manejar NaN e infinidades en una ruta de código separada.
Además, debe tener versiones de ceil y floor que devuelvan números de coma flotante si desea cumplir con IEEE 754 .
Tal vez porque otros lenguajes hacen esto también, por lo que es un comportamiento generalmente aceptado. (Por buenas razones, como se muestra en las otras respuestas)