Display a decimal in scientific notation
Asked Answered
E

13

255

How can I display 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.

Epigraphic answered 2/8, 2011 at 14:16 Comment(2)
kinda doubleposting, you could have used this topic you just started: #6913666Avens
nah, not at all. I wanted to separate this into the easy question (how to do it in Python) and the hard, obscure question that I doubt anyone will answer (how to do it in Django). Notice how this already has an answer. I'm now halfway to my final answer instead of 0% if I had posted them together. Besides that, separating the questions makes it easier for people to search for the answers. E.,g if Bob is searching for a decimal formatting question he might skip a SO questin with Django in the title.Epigraphic
A
229
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'
Arundell answered 2/8, 2011 at 14:19 Comment(2)
As an aside, despite the format % values syntax still being used even within the Python 3 standard library, I believe it's technically deprecated in Python 3, or at least not the recommended formatting method, and the current recommended syntax, starting with Python 2.6, would be '{0:.2E}'.format(Decimal('40800000000.00000000000000')) (or '{:.2E}' in Python 2.7+). While not strictly useful for this situation, due to the additional characters for no added functionality, str.format does allow for more complex mixing/rearranging/reutilizing of format arguments.Lachesis
@CharlieParker Use format. It's more jazzy.Crosspurpose
U
185

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'
Unreasoning answered 8/11, 2013 at 16:44 Comment(1)
This syntax also applies to f-strings in 3.6+ f"{Decimal('40800000000.00000000000000'):.2E}"Resorcinol
O
73

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

Osmic answered 12/3, 2017 at 15:47 Comment(7)
The point of using Decimal is to get exact and arbitrary precision decimal arithmetic. It is not equivalent to using a float.Sunder
@Sunder Thanks for the clarification. Changed my answer.Osmic
Is there a way to get back from this to float?Cohbath
@Cohbath just doing float(x) will convert x into float.Osmic
Is there a difference between e and E ?Fart
I don't think so, no.Osmic
@minseong: from the documentation: "Scientific notation. Same as 'e' except it uses an upper case ‘E’ as the separator character"Jefferson
W
49

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)

Wendiewendin answered 26/2, 2018 at 10:38 Comment(4)
Should be accepted answer. f-strings is the future of python string formatting :)Homeward
As an fyi to future readers like myself: if you don't care to control the number of digits and don't mind floating point errors, you can simply use {num:E}, where e.g. num = 40800000000.00000000000000Oliphant
For information about formatting #45310754Wendiewendin
Following on from shayaan's recommendation that is f"{num:E}"Theme
C
19

This is a consolidated list of the "Simple" Answers & Comments.

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))
Countertenor answered 27/10, 2019 at 4:29 Comment(1)
Example Usage: github.com/JayRizzo/rg_code/blob/master/class_act/…Countertenor
P
12

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

Philharmonic answered 2/8, 2011 at 14:22 Comment(0)
S
5

This worked best for me:

import decimal
'%.2E' % decimal.Decimal('40800000000.00000000000000')
# 4.08E+10
Silva answered 12/5, 2016 at 8:9 Comment(0)
P
4

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
Pera answered 6/1, 2013 at 22:6 Comment(1)
Just "{:.2e}".format(n) returns '3.39e+7800' in Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:06:53) [MSC v.1600 64 bit (AMD64)] on win32.Unreasoning
W
4

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().

Washwoman answered 26/2, 2014 at 11:37 Comment(0)
L
4

I prefer Python 3.x way.

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

4 indicates how many digits are shown shown in the floating part.

cal = 123.4567
totalDigitInFloatingPArt = 4
print(f"result {cal:.{totalDigitInFloatingPArt}E} ")
Luanneluanni answered 11/9, 2019 at 3:33 Comment(0)
C
2

Adding an updated answer to show how to apply e notation to small numbers only

value = 0.1
a = "{:,}".format(value) if value >= 0.001 else "{:,.3e}".format(value)
print(a) # 0.1

value = 0.00002488
a = "{:,}".format(value) if value >= 0.001 else "{:,.3e}".format(value)
print(a) # 2.488e-05
Channa answered 14/10, 2021 at 10:41 Comment(0)
B
1

Here is the simplest one I could find.

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

('E' is not case sensitive. You can also use '.2e')

Beachhead answered 5/4, 2020 at 22:5 Comment(0)
B
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
Bitterweed answered 12/1, 2015 at 10:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.