Display a decimal in scientific notation

Posted on

Question :

Display a decimal in scientific notation

How can I display this:

Decimal(‘40800000000.00000000000000’) as ‘4.08E+10’?

I’ve tried this:

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

But it has those extra 0’s.

``````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'
``````

Here’s an example using the `format()` function:

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

Instead of format, you can also use f-strings:

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

``````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`.

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

OR Without `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
# =====================================
``````

Comparing

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

So for Python 3, you can switch between any of the three for now.

My Fav:

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

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:])
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
``````

``````import decimal