Arrondir un nombre à virgule flottante à l'entier le plus proche?


128

Comme le titre l'indique, je veux prendre un nombre à virgule flottante et l'arrondir à l'entier le plus proche. Cependant, si ce n'est pas un tout, je veux TOUJOURS arrondir la variable, quelle que soit sa proximité avec le prochain entier supérieur. Y a-t-il un moyen de faire cela?


2
Une difficulté possible est que les formats à virgule flottante IEEE peuvent représenter des nombres si grands que la grandularité est supérieure à 1. Ainsi, même si vous pouvez arrondir x vers le bas, arrondir x + 1 vers le bas ne vous donnera pas le résultat attendu.
dmckee --- ex-moderator chaton

Veuillez poster quelques exemples.
Ashwini Chaudhary

Réponses:


179

Facile

print int(x)

fonctionnera également.


7
int (0.6) = 0 au lieu de 1
Helin Wang

39
@HelinWang C'est exactement ce que OP a demandé.
Petr Peller

5
Cela semble être l'approche la plus pythonique.
Gyan Veda

23
Cela fonctionne bien pour les nombres positifs, mais les nombres négatifs seront arrondis:int(-23.3) == 23
Alex Riley

2
et ne fonctionne pas pour un nombre au-delà de la plage entière telle que 600851475143, il signalera essentiellement une erreur de mémoire.
Muyide Ibukun

77

L'un de ceux-ci devrait fonctionner:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2

14
La sortie de math.truncest un entier, tandis que la sortie de math.floorest un flottant.
evedovelli

6
@evedovelli: Plus vraiment. type(math.floor(1.51)) -> intet à type(math.trunc(1.51)) -> intpartir depython 3.6.0
SKPS

4
Ces options sont plus explicites que "int (x)" et sont donc plus pythoniques.
Tristan

44
x//1

L' //opérateur retourne l'étage de la division. Puisque la division par 1 ne change pas votre nombre, cela équivaut au plancher mais aucune importation n'est nécessaire. Remarques:

  1. Cela renvoie un float
  2. Cela tourne vers -∞

Bel ajout. int(-1.1) == -1tandis que -1.1//1 == -2.0cependant decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(comme documenté, la revendication 2 n'est pas vraie pour decimal), donc se fier à son //comportement n'est pas totalement stable, même aujourd'hui.
Tino

28

Pour obtenir un résultat en virgule flottante, utilisez simplement:

round(x-0.5)

Cela fonctionne également pour les nombres négatifs.


6
extrêmement sophistiqué qui est
Alon


9

beaucoup de gens disent d'utiliser int(x), et cela fonctionne bien dans la plupart des cas, mais il y a un petit problème. Si le résultat de OP est:

x = 1.9999999999999999

il s'arrondira à

x = 2

après le 16e 9, il s'arrondira. Ce n'est pas un gros problème si vous êtes sûr de ne jamais rencontrer une telle chose. Mais c'est quelque chose à garder à l'esprit.


17
C'est parce qu'il 1.9999999999999999est en fait égal à 2.0dans la représentation float64 interne. C'est à dire. il est déjà arrondi dès qu'il est analysé en un flottant, car un flottant de 64 bits ne peut pas représenter autant de chiffres significatifs. Vous pouvez le vérifier en évaluant 1.9999999999999999 == 2.0. Et si vous pensez que l'opération d'égalité effectue un arrondi sur les flottants, vous pouvez comparer la représentation binaire avec struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0), qui est également égale.
blubberdiblub

4
Et si c'est exactement votre argument, alors je ne vois pas ce qui ne va pas int(). La valeur est déjà de 2,0 et il la convertira heureusement en 2.
blubberdiblub

1
Si l'intention d'OP (ou de quiconque lit cela à l'avenir) est d'utiliser l'entier le plus proche (et non la valeur arrondie) pour une raison quelconque, alors ce serait quelque chose à garder à l'esprit.
lokilindo

3
@lokilindo Mais cela n'a rien à voir avec int(), cela a uniquement à voir avec une mauvaise utilisation defloat , comme 1.9999999999999999arrondi à 2.0 au moment de la compilation (alors qu'il int()est appelé au moment de l'exécution). Si vous utilisez le bon type de données pour la variable, tout fonctionne comme prévu: int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))donne1
Tino

6

Si vous ne souhaitez pas importer de mathématiques, vous pouvez utiliser:

int(round(x))

Voici un morceau de documentation:

>>> help(round)
Help on built-in function round in module __builtin__:

round(...)
    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.

Merci pour votre réponse. La prochaine fois, vous obtiendrez une meilleure réception si vous écrivez le bon code (parenthèses fermées) et fournissez de la documentation.
Geoff

2
rounda déjà été discutée et rejetée comme réponse lorsque cette question a été posée il y a un an. OP veut math.floor.
Adam Smith

3

Si vous travaillez avec numpy, vous pouvez utiliser la solution suivante qui fonctionne également avec des nombres négatifs (elle fonctionne également sur des tableaux)

import numpy as np
def round_down(num):
    if num < 0:
        return -np.ceil(abs(num))
    else:
        return np.int32(num)
round_down = np.vectorize(round_down)

round_down([-1.1, -1.5, -1.6, 0, 1.1, 1.5, 1.6])
> array([-2., -2., -2.,  0.,  1.,  1.,  1.])

Je pense que cela fonctionnera également si vous utilisez simplement le mathmodule au lieu du numpymodule.


1

Je ne sais pas si vous avez résolu cela, mais je tombe juste sur cette question. Si vous voulez vous débarrasser des points décimaux, vous pouvez utiliser int (x) et cela éliminera tous les chiffres décimaux. Il n'est pas nécessaire d'utiliser round (x).


1

Faites simplement arrondi (x-0,5), cela retournera toujours la prochaine valeur entière arrondie vers le bas de votre Float. Vous pouvez également arrondir facilement par faire un tour (x + 0,5)


-1

Cela peut être très simple, mais ne pourriez-vous pas simplement arrondir le chiffre à moins 1? Par exemple:

number=1.5
round(number)-1
> 1

4
Cela donne la mauvaise réponse pour les entiers entiers. Par exemple, 2.0 arrondi est égal à 2, et si vous soustrayez 1, vous obtenez le résultat incorrect 1.
Pascal Cuoq

@PascalCuoq Je ne comprends pas votre problème. Voulez-vous 1.0 comme résultat? Parce qu'OP voulait clairement arrondir le nombre au plus proche integer.
bad_keypoints

1
@bad_keypoints Je ne pense pas que l'OP veuille arrondir 2.0 à 1.
Pascal Cuoq

@PascalCuoq désolé, je viens de regarder la réponse dans le fil de commentaires dont nous sommes.
bad_keypoints

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.