web-dev-qa-db-fra.com

Pourquoi les opérations math.ceil () et math.floor () de Python renvoient-elles des flottants au lieu d’entiers?

Quelqu'un peut-il expliquer cela (directement du docs - emphase mien):

math.ceil (x) Renvoie le plafond de x sous forme de float , le plus petit entier valeur supérieure ou égale à x.

math.floor (x) Renvoie le plancher de x sous forme de float , le plus grand entier valeur inférieure ou égale à x.

Pourquoi .ceil et .floor renverraient-ils des nombres flottants alors qu'ils sont par définition supposés calculer des entiers?


EDIT:

Eh bien, cela a eu de très bons arguments pour expliquer pourquoi devrait renvoyer des flotteurs, et je commençais juste à m'habituer à l'idée, lorsque @ jcollado a fait remarquer que ils (en fait) font retournent des ints dans Python 3 ...

161
Yarin

La plage des nombres en virgule flottante dépasse généralement celle des nombres entiers. En renvoyant une valeur à virgule flottante, les fonctions peuvent renvoyer une valeur sensible pour les valeurs d'entrée situées en dehors de la plage d'entiers pouvant être représentées.

Considérez: Si floor() a renvoyé un entier, que doit retourner floor(1.0e30)?

Maintenant, bien que les entiers de Python soient maintenant d'une précision arbitraire, ce ne fut pas toujours le cas. Les fonctions de bibliothèque standard sont des enveloppes minces autour des fonctions de bibliothèque C équivalentes.

95
Greg Hewgill

Comme indiqué par d’autres réponses, python renvoie des flottants, probablement pour des raisons historiques, afin d’éviter les problèmes de débordement. Cependant, ils renvoient des entiers dans python 3.

>>> import math
>>> type(math.floor(3.1))
<class 'int'>
>>> type(math.ceil(3.1))
<class 'int'>

Vous pouvez trouver plus d'informations dans PEP 3141 .

91
jcollado

Parce que la bibliothèque mathématique de python est une enveloppe fine autour de la bibliothèque mathématique C qui renvoie des flottants.

17
Charles

La source de votre confusion est évidente dans votre commentaire:

L’intérêt des opérations plancher/sol est de convertir les flotteurs en nombres entiers!

Le point central des opérations de plafond et de plancher consiste à arrondir les données en virgule flottante aux valeurs intégrales . Ne pas faire de conversion de type. Les utilisateurs qui ont besoin d'obtenir des valeurs entières peuvent effectuer une conversion explicite à la suite de l'opération.

Notez qu'il ne serait pas possible d'implémenter un arrondi à valeur intégrale aussi trivialement si tout ce dont vous disposiez était une opération ceil ou float qui renvoyait un entier. Vous devez d’abord vérifier que l’entrée se situe dans la plage d’entiers pouvant être représentée, puis appeler la fonction. vous auriez besoin de gérer NaN et les infinis dans un chemin de code séparé.

De plus, vous devez disposer de versions de ceil et de floor qui renvoient des nombres à virgule flottante si vous souhaitez vous conformer à IEEE 754 .

16
Stephen Canon

Avant Python 2.4, un entier ne pouvait pas contenir toute la gamme des nombres réels tronqués.

http://docs.python.org/whatsnew/2.4.html#pep-237-unifying-long-integers-and-integers

5
Mark Ransom

Parce que la plage pour les floats est supérieure à celle des entiers - le renvoi d'un entier peut déborder

4
kyle

C'est une question très intéressante! En tant que float, quelques bits sont nécessaires pour stocker l’exposant (= bits_for_exponent), tout nombre en virgule flottante supérieur à 2**(float_size - bits_for_exponent) sera toujours une valeur intégrale! À l'autre extrême, un float avec un exposant négatif donnera l'un de 1, 0 ou -1. Cela rend la discussion de plage entière contre gamme de flotteurs moot car ces fonctions renverront simplement le numéro d'origine chaque fois que le nombre est en dehors de la plage du type entier. Les fonctions python sont des wrappers de la fonction C. Il s’agit donc vraiment d’un défaut des fonctions C où elles auraient dû renvoyer un entier et obliger le programmeur à effectuer la plage/NaN/Inf à vérifier avant d'appeler ceil/floor.

Ainsi, la réponse logique est la seule fois où ces fonctions sont utiles, elles renverraient une valeur comprise dans un intervalle entier et le fait qu'elles renvoient un float est un erreur et vous êtes très intelligent pour réaliser cela!

4
Justin Finnerty

Peut-être parce que d'autres langues le font aussi, il s'agit donc d'un comportement généralement accepté. (Pour de bonnes raisons, comme indiqué dans les autres réponses)

1
Almo