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.

Greg
la source
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'
eumiro
la source
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
121

Voici un exemple utilisant la format()fonction:

>>> "{:.2E}".format(Decimal('40800000000.00000000000000'))
'4.08E+10'

Au lieu du format, vous pouvez également utiliser des f-strings :

>>> f"{Decimal('40800000000.00000000000000'):.2E}"
'4.08E+10'
Cees Timmerman
la source
3
Cette syntaxe s'applique également aux chaînes f dans 3.6+f"{Decimal('40800000000.00000000000000'):.2E}"
Tritium21
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

patapouf_ai
la source
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)

Eulenfuchswiesel
la source
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
ubershmekel
la source
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
Matthew Fitch
la source
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))
JayRizzo
la source
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} ")
snr
la source
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().

MikeM
la source
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")

Rahat Ibrahim
la source
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
Andrej
la source