12
votes

obtenir ceil () de décimale à Python?

Y a-t-il un moyen d'obtenir le plafond d'une grande décimale de précision en python? XXX

MATH arrose la valeur et retourne la valeur non précise


1 commentaires

Je suis nouveau à Python, je viens de commencer hier en fait. Stupédié sur ce problème dans mon deuxième programme de pratique (le premier était bien sûr l'obligatoire «Print» Bonjour, World! '; »). Donc, je trouve difficile de juger la meilleure réponse à cela. La solution décimale.context de Matthew Flaschen a travaillé dans mon cas particulier. Mais j'aimerais que les autres optimisent la meilleure solution (aussi être utiles pour les débutants comme moi si vous pouvez expliquer pourquoi une approche donnée fonctionne mieux) et je reviendrai et accepterai.


6 Réponses :


4
votes

Vous pouvez le faire en utilisant l'option de mode de précision et d'arrondi du constructeur de contexte.

ctx = decimal.Context(prec=1, rounding=decimal.ROUND_CEILING)
ctx.divide(decimal.Decimal(800000000000000000001), decimal.Decimal(100000000000000000000))


3 commentaires

Parfait :) --- Terminer la limite de caractères ---


@Alex Désolé devait partir avant 6 minutes. Merci pour le rappel


-1. Cela ne généralise pas bien; Il ne se passe que dans ce cas car le résultat est compris entre [1, 10]. Essayez le même calcul avec décimal (123) / décimal (10), par exemple, et vous obtiendrez un résultat de décimal ('2e + 1') .



0
votes
>>> decimal.Context(rounding=decimal.ROUND_CEILING).quantize(
...   decimal.Decimal(800000000000000000001)/100000000000000000000, 0)
Decimal('9')

1 commentaires

Notez que cette solution a des problèmes pour décimal avec une valeur importante: par exemple, si vous essayez c.quantize (décimal.decimal ('1e100'), 1) avec votre contexte C , vous obtiendrez une exception invalidorsération .



0
votes
def decimal_ceil(x):
    int_x = int(x)
    if x - int_x == 0:
        return int_x
    return int_x + 1

0 commentaires

5
votes
x = decimal.Decimal('8.00000000000000000000001')
with decimal.localcontext() as ctx:
    ctx.prec=100000000000000000
    ctx.rounding=decimal.ROUND_CEILING
    y = x.to_integral_exact()

1 commentaires

C'est bon, mais il n'est pas nécessaire de changer la précision du contexte ici. TO_INTEGRAL_EXACT prend également un argument d'arrondi , afin que vous puissiez éviter de jouer avec le contexte.



28
votes

La voie la plus directe de prendre le plafond d'une instance décimale x est d'utiliser x.to_integral_exact (arrondi = rond_ceiling) . Il n'y a pas besoin de gâcher avec le contexte ici. Notez que cela définit le inexacte et arrondi drapeaux le cas échéant; Si vous ne voulez pas que les indicateurs touchent, utilisez x.to_integal_value (arrondi = rond_ceiling) à la place. Exemple: xxx

Contrairement à la plupart des méthodes décimales, le to_integral_exact et to_integal_value n'est pas affecté par la précision du contexte actuel , donc vous n'avez pas à vous soucier de changer de précision: xxx

d'ailleurs, dans python 3.x, math.ceil fonctionne exactement Comme vous le souhaitez, sauf qu'il renvoie un int plutôt que par une instance décimale . Cela fonctionne parce que math.ceil est surchargeable pour les types personnalisés dans Python 3. Dans Python 2, math.ceil convertit simplement l'instance décimal à un float d'abord, perdez potentiellement des informations dans le processus, vous pouvez donc vous retrouver avec des résultats incorrects.


2 commentaires

Juste pour la complétude: dans Python 2.x Math.Ceuil ne fonctionne pas comme prévu: il convertit la décimale en float en premier. À cause de ce int (pla (d ('1.0000000000000001'))) évalue à 1 en Python 2.x et à 2 dans Python 3.x


@Antayhatchkins: merci, bon point. J'ai édité cette information dans la réponse.



0
votes

Utilisez simplement une puissance pour faire cela. Importer math xxx


0 commentaires