Mostrar un decimal en notación científica


161

¿Cómo puedo mostrar esto?

¿Decimal ('40800000000.00000000000000') como '4.08E + 10'?

He intentado esto:

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

Pero tiene esos 0 extra.


3
un poco doble, podría haber usado este tema que acaba de comenzar: stackoverflow.com/questions/6913166/…
Samuele Mattiuzzo

13
no, en absoluto Quería separar esto en la pregunta fácil (cómo hacerlo en Python) y la pregunta difícil y oscura que dudo que alguien responda (cómo hacerlo en Django). Observe cómo esto ya tiene una respuesta. Ahora estoy a medio camino de mi respuesta final en lugar de 0% si los hubiera publicado juntos. Además de eso, separar las preguntas hace que sea más fácil para las personas buscar las respuestas. E., g si Bob está buscando una pregunta de formato decimal, puede saltear una búsqueda SO con Django en el título.
Greg

sí, fue solo para mi interés: P es más fácil seguir un hilo. básicamente es similar a mi respuesta (solo un "bit" más específico). Estoy esperando una respuesta de Django también, por cierto.
Samuele Mattiuzzo

Respuestas:


157
from decimal import Decimal

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

# returns '4.08E+10'

En su '40800000000.00000000000000' hay muchos ceros más significativos que tienen el mismo significado que cualquier otro dígito. Es por eso que tienes que decir explícitamente dónde quieres parar.

Si desea eliminar todos los ceros finales automáticamente, puede intentar:

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
Por otro lado, a pesar de que la format % valuessintaxis todavía se usa incluso dentro de la biblioteca estándar de Python 3, creo que está técnicamente en desuso en Python 3, o al menos no el método de formato recomendado, y la sintaxis recomendada actual, comenzando con Python 2.6, sería'{0:.2E}'.format(Decimal('40800000000.00000000000000')) ( o '{:.2E}'en Python 2.7+). Si bien no es estrictamente útil para esta situación, debido a los caracteres adicionales para no agregar funcionalidad, str.formatpermite una mezcla / reorganización / reutilización más compleja de los argumentos de formato.
JAB

¿Qué hay de Python 3?
Charlie Parker

44
@CharlieParker Use format . Es más jazzy .
Mateen Ulhaq


37

Dado su número

x = Decimal('40800000000.00000000000000')

A partir de Python 3,

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

es la forma recomendada de hacerlo

esignifica que desea notación científica y .2quiere decir 2 dígitos después del punto. Entonces obtendrásx.xxE±n


1
El punto de usar Decimal es obtener aritmética decimal de precisión exacta y arbitraria. No es equivalente a usar un flotador.
asmeurer

@asmeurer Gracias por la aclaración. Cambié mi respuesta.
patapouf_ai

¿Hay alguna manera de regresar de esto para flotar?
olenscki

@olenscki solo haciendo float(x)convertirá x en flotante.
patapouf_ai

33

Nadie mencionó la forma abreviada del .formatmétodo:

Necesita al menos Python 3.6

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

(Creo que es lo mismo que Cees Timmerman, solo un poco más corto)


3
Se debe aceptar la respuesta. f-strings es el futuro del formato de cadenas de python :)
Gandalf Saxe

1
Como información para futuros lectores como yo: si no le importa controlar el número de dígitos y no le importan los errores de coma flotante, simplemente puede usar {num:E}, donde, por ejemplo, num = 40800000000.00000000000000
Shayaan


4

Mis decimales son demasiado grandes, %Easí que tuve que improvisar:

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)

Aquí hay un ejemplo de uso:

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

3
Acaba de "{:.2e}".format(n)regresar '3.39e+7800'en Python 3.3.2 (v3.3.2: d047928ae3f6, 16 de mayo de 2013, 00:06:53) [MSC v.1600 64 bit (AMD64)] en win32.
Cees Timmerman el

4

Esto funcionó mejor para mí:

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

4

Esta es una lista consolidada de las respuestas y comentarios "simples" .

PITÓN 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
# =====================================

O sin IMPORT's

# 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
# =====================================

Comparando

# =====================================
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

Entonces, para Python 3, puedes cambiar entre cualquiera de los tres por ahora.

Mi favorito:

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

3

Prefiero Python 3.x forma.

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

4 indica cuántos dígitos se muestran en la parte flotante.

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

2

Para convertir un decimal a notación científica sin necesidad de especificar la precisión en la cadena de formato, y sin incluir ceros finales, actualmente estoy usando

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

Para mantener los ceros a la izquierda, simplemente elimine el normalize().


1

Aquí está el más simple que pude encontrar.

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

('E' no distingue entre mayúsculas y minúsculas. También puede usar '.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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.