Afficher un décimal en notation scientifique


161

Comment puis-je afficher ceci:

Décimal ('40800000000.00000000000000') comme '4.08E + 10'?

J'ai essayé ceci:

>>> '%E' % Decimal('40800000000.00000000000000')
'4.080000E+10'

Mais il a ces 0 supplémentaires.


3
un peu en double, vous auriez pu utiliser ce sujet que vous venez de commencer: stackoverflow.com/questions/6913166/...
Samuele Mattiuzzo

13
non, pas du tout. Je voulais séparer cela en la question facile (comment le faire en Python) et la question difficile et obscure à laquelle je doute que quiconque répondra (comment le faire dans Django). Remarquez comment cela a déjà une réponse. Je suis maintenant à mi-chemin de ma réponse finale au lieu de 0% si je les avais postées ensemble. En plus de cela, séparer les questions permet aux gens de rechercher plus facilement les réponses. E., g si Bob recherche une question de formatage décimal, il peut sauter une requête SO avec Django dans le titre.
Greg

oui, c'était juste pour mon intérêt: P c'est plus facile de suivre un fil. fondamentalement, c'est similaire à ma réponse (juste un "peu" plus précis). j'espère aussi une réponse django, btw.
Samuele Mattiuzzo

Réponses:


157
from decimal import Decimal

'%.2E' % Decimal('40800000000.00000000000000')

# returns '4.08E+10'

Dans votre '40800000000.00000000000000', il y a beaucoup plus de zéros significatifs qui ont la même signification que n'importe quel autre chiffre. C'est pourquoi vous devez dire explicitement où vous voulez vous arrêter.

Si vous souhaitez supprimer automatiquement tous les zéros de fin, vous pouvez essayer:

def format_e(n):
    a = '%E' % n
    return a.split('E')[0].rstrip('0').rstrip('.') + 'E' + a.split('E')[1]

format_e(Decimal('40800000000.00000000000000'))
# '4.08E+10'

format_e(Decimal('40000000000.00000000000000'))
# '4E+10'

format_e(Decimal('40812300000.00000000000000'))
# '4.08123E+10'

22
En passant, malgré la format % valuessyntaxe toujours utilisée même dans la bibliothèque standard Python 3, je pense qu'elle est techniquement obsolète dans Python 3, ou du moins pas la méthode de formatage recommandée, et la syntaxe actuelle recommandée, à commencer par Python 2.6, serait '{0:.2E}'.format(Decimal('40800000000.00000000000000'))( ou '{:.2E}'en Python 2.7+). Bien que cela ne soit pas strictement utile dans cette situation, en raison des caractères supplémentaires pour aucune fonctionnalité ajoutée, str.formatpermet un mélange / réarrangement / réutilisation plus complexe des arguments de format.
JAB

qu'en est-il de python 3?
Charlie Parker

4
@CharlieParker Use format. C'est plus jazzy .
Mateen Ulhaq


37

Compte tenu de votre numéro

x = Decimal('40800000000.00000000000000')

À partir de Python 3,

'{:.2e}'.format(x)

est la manière recommandée de le faire.

esignifie que vous voulez une notation scientifique et .2que vous voulez 2 chiffres après le point. Ainsi vous obtiendrezx.xxE±n


1
Le but d'utiliser Decimal est d'obtenir une arithmétique décimale de précision exacte et arbitraire. Cela n'équivaut pas à utiliser un flotteur.
asmeurer

@asmeurer Merci pour la clarification. J'ai changé ma réponse.
patapouf_ai

Y a-t-il un moyen de revenir de cela pour flotter?
olenscki

@olenscki ne fait float(x)que convertir x en float.
patapouf_ai

33

Personne n'a mentionné la forme courte de la .formatméthode:

Nécessite au moins Python 3.6

f"{Decimal('40800000000.00000000000000'):.2E}"

(Je crois que c'est la même chose que Cees Timmerman, juste un peu plus court)


3
Devrait être une réponse acceptée. f-strings est l'avenir du formatage des chaînes python :)
Gandalf Saxe

1
En tant que fyi pour les futurs lecteurs comme moi: si vous ne vous souciez pas de contrôler le nombre de chiffres et que les erreurs en virgule flottante ne vous {num:E}dérangent pas, vous pouvez simplement utiliser , où par exemple num = 40800000000.00000000000000
Shayaan


4

Mes décimales sont trop grandes pour %Edonc j'ai dû improviser:

def format_decimal(x, prec=2):
    tup = x.as_tuple()
    digits = list(tup.digits[:prec + 1])
    sign = '-' if tup.sign else ''
    dec = ''.join(str(i) for i in digits[1:])
    exp = x.adjusted()
    return '{sign}{int}.{dec}e{exp}'.format(sign=sign, int=digits[0], dec=dec, exp=exp)

Voici un exemple d'utilisation:

>>> n = decimal.Decimal(4.3) ** 12314
>>> print format_decimal(n)
3.39e7800
>>> print '%e' % n
inf

3
"{:.2e}".format(n)Retourne simplement '3.39e+7800'en Python 3.3.2 (v3.3.2: d047928ae3f6, 16 mai 2013, 00:06:53) [MSC v.1600 64 bits (AMD64)] sur win32.
Cees Timmerman

4

Cela a fonctionné le mieux pour moi:

import decimal
'%.2E' % decimal.Decimal('40800000000.00000000000000')
# 4.08E+10

4

Ceci est une liste consolidée des "Simple" réponses et commentaires .

PYTHON 3

from decimal import Decimal

x = '40800000000.00000000000000'
# Converted to Float
x = Decimal(x)

# ===================================== # `Dot Format`
print("{0:.2E}".format(x))
# ===================================== # `%` Format
print("%.2E" % x)
# ===================================== # `f` Format
print(f"{x:.2E}")
# =====================================
# ALL Return: 4.08E+10
print((f"{x:.2E}") == ("%.2E" % x) == ("{0:.2E}".format(x)))
# True
print(type(f"{x:.2E}") == type("%.2E" % x) == type("{0:.2E}".format(x)))
# True
# =====================================

OU Sans IMPORTl »

# NO IMPORT NEEDED FOR BASIC FLOATS
y = '40800000000.00000000000000'
y = float(y)

# ===================================== # `Dot Format`
print("{0:.2E}".format(y))
# ===================================== # `%` Format
print("%.2E" % y)
# ===================================== # `f` Format
print(f"{y:.2E}")
# =====================================
# ALL Return: 4.08E+10
print((f"{y:.2E}") == ("%.2E" % y) == ("{0:.2E}".format(y)))
# True
print(type(f"{y:.2E}") == type("%.2E" % y) == type("{0:.2E}".format(y)))
# True
# =====================================

Comparant

# =====================================
x
# Decimal('40800000000.00000000000000')
y
# 40800000000.0

type(x)
# <class 'decimal.Decimal'>
type(y)
# <class 'float'>

x == y
# True
type(x) == type(y)
# False

x
# Decimal('40800000000.00000000000000')
y
# 40800000000.0

Donc, pour Python 3, vous pouvez basculer entre l'un des trois pour le moment.

Mon préféré:

print("{0:.2E}".format(y))

3

Je préfère la manière Python 3.x.

cal = 123.4567
print(f"result {cal:.4E}")

4 indique le nombre de chiffres affichés dans la partie flottante.

cal = 123.4567
totalDigitInFloatingPArt = 4
print(f"result {cal:.{totalDigitInFloatingPArt}E} ")

2

Pour convertir un décimal en notation scientifique sans avoir à spécifier la précision dans la chaîne de format, et sans inclure les zéros de fin, j'utilise actuellement

def sci_str(dec):
    return ('{:.' + str(len(dec.normalize().as_tuple().digits) - 1) + 'E}').format(dec)

print( sci_str( Decimal('123.456000') ) )    # 1.23456E+2

Pour conserver les zéros de fin, supprimez simplement le fichier normalize().


1

Voici le plus simple que j'ai pu trouver.

format(40800000000.00000000000000, '.2E')
#'4.08E+10'

("E" n'est pas sensible à la casse. Vous pouvez également utiliser ".2e")


0
def formatE_decimal(x, prec=2):
    """ Examples:
    >>> formatE_decimal('0.1613965',10)
    '1.6139650000E-01'
    >>> formatE_decimal('0.1613965',5)
    '1.61397E-01'
    >>> formatE_decimal('0.9995',2)
    '1.00E+00'
    """
    xx=decimal.Decimal(x) if type(x)==type("") else x 
    tup = xx.as_tuple()
    xx=xx.quantize( decimal.Decimal("1E{0}".format(len(tup[1])+tup[2]-prec-1)), decimal.ROUND_HALF_UP )
    tup = xx.as_tuple()
    exp = xx.adjusted()
    sign = '-' if tup.sign else ''
    dec = ''.join(str(i) for i in tup[1][1:prec+1])   
    if prec>0:
        return '{sign}{int}.{dec}E{exp:+03d}'.format(sign=sign, int=tup[1][0], dec=dec, exp=exp)
    elif prec==0:
        return '{sign}{int}E{exp:+03d}'.format(sign=sign, int=tup[1][0], exp=exp)
    else:
        return None
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.