Display a decimal in scientific notation

偶尔善良 提交于 2019-11-26 07:38:22
eumiro
from decimal import Decimal

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

# returns '4.08E+10'

In your '40800000000.00000000000000' there are many more significant zeros that have the same meaning as any other digit. That's why you have to tell explicitly where you want to stop.

If you want to remove all trailing zeros automatically, you can try:

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'
Cees Timmerman

Here's an example using the format() function:

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

Given your number

x = Decimal('40800000000.00000000000000')

Starting from Python 3,

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

is the recommended way to do it.

e means you want scientific notation, and .2 means you want 2 digits after the dot. So you will get x.xxE±n

No one mentioned the short form of the .format method:

Needs at least Python 3.6

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

(I believe it's the same as Cees Timmerman, just a bit shorter)

See tables from Python string formatting to select the proper format layout. In your case it's %.2E.

My decimals are too big for %E so I had to improvize:

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)

Here's an example usage:

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

This worked best for me:

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

To convert a Decimal to scientific notation without needing to specify the precision in the format string, and without including trailing zeros, I'm currently using

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

To keep any trailing zeros, just remove the normalize().

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!