Tampilkan desimal dalam notasi ilmiah

161

Bagaimana saya bisa menampilkan ini:

Desimal ('40800000000.00000000000000') sebagai '4.08E + 10'?

Saya sudah mencoba ini:

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

Tetapi memiliki 0 ekstra itu.

Greg
sumber
3
agak melipatgandakan, Anda bisa menggunakan topik yang baru saja Anda mulai: stackoverflow.com/questions/6913166/…
Samuele Mattiuzzo
13
nah, tidak sama sekali. Saya ingin memisahkan ini menjadi pertanyaan mudah (bagaimana melakukannya dengan Python) dan pertanyaan yang sulit dan tidak jelas yang saya ragu akan dijawab siapa pun (bagaimana melakukannya di Django). Perhatikan bagaimana ini sudah memiliki jawaban. Saya sekarang setengah jalan ke jawaban akhir saya alih-alih 0% jika saya telah mempostingnya bersama. Selain itu, memisahkan pertanyaan memudahkan orang mencari jawaban. E., g jika Bob mencari pertanyaan pemformatan desimal, ia mungkin melewatkan pencarian SO dengan Django dalam judul.
Greg
ya, itu hanya untuk minat saya: P lebih mudah untuk mengikuti satu utas. pada dasarnya ini mirip dengan jawaban saya (hanya "sedikit" lebih spesifik). Saya berharap untuk jawaban Django juga, btw.
Samuele Mattiuzzo

Jawaban:

157
from decimal import Decimal

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

# returns '4.08E+10'

Di '40800000000.00000000000000' Anda, ada banyak nol signifikan yang memiliki arti yang sama dengan digit lainnya. Itu sebabnya Anda harus memberi tahu secara eksplisit ke mana Anda ingin berhenti.

Jika Anda ingin menghapus semua nol trailing secara otomatis, Anda dapat mencoba:

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
sumber
22
Sebagai tambahan, meskipun format % valuessintaks masih digunakan bahkan dalam pustaka standar Python 3, saya percaya itu secara teknis ditinggalkan dalam Python 3, atau setidaknya bukan metode format yang direkomendasikan, dan sintaks yang direkomendasikan saat ini, dimulai dengan Python 2.6, akan menjadi '{0:.2E}'.format(Decimal('40800000000.00000000000000'))( atau '{:.2E}'dengan Python 2.7+). Meskipun tidak sepenuhnya berguna untuk situasi ini, karena karakter tambahan tanpa fungsi tambahan, str.formatmemungkinkan pencampuran / penyusunan ulang / pemanfaatan kembali argumen format yang lebih kompleks.
JAB
bagaimana dengan python 3?
Charlie Parker
4
@CharlieParker Gunakan format. Ini lebih jazzy .
Mateen Ulhaq
121

Berikut ini contoh menggunakan format()fungsi:

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

Alih-alih memformat, Anda juga dapat menggunakan f-string :

>>> f"{Decimal('40800000000.00000000000000'):.2E}"
'4.08E+10'
Cees Timmerman
sumber
3
Sintaks ini juga berlaku untuk f-string di 3.6+f"{Decimal('40800000000.00000000000000'):.2E}"
Tritium21
37

Diberi nomor Anda

x = Decimal('40800000000.00000000000000')

Mulai dari Python 3,

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

adalah cara yang disarankan untuk melakukannya.

eberarti Anda ingin notasi ilmiah, dan .2berarti Anda ingin 2 digit setelah titik. Jadi, Anda akan mendapatkannyax.xxE±n

patapouf_ai
sumber
1
Tujuan dari menggunakan Desimal adalah untuk mendapatkan aritmatika desimal presisi tepat dan sewenang-wenang. Itu tidak setara dengan menggunakan pelampung.
penanggung jawab
@asmeurer Terima kasih atas klarifikasi. Mengubah jawaban saya.
patapouf_ai
Apakah ada cara untuk kembali dari mengapung?
olenscki
@olenscki hanya melakukan float(x)akan mengubah x menjadi float.
patapouf_ai
33

Tidak ada yang menyebutkan bentuk singkat dari .formatmetode ini:

Membutuhkan setidaknya Python 3.6

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

(Saya percaya itu sama dengan Cees Timmerman, hanya sedikit lebih pendek)

Eulenfuchswiesel
sumber
3
Harus diterima jawaban. f-string adalah masa depan format string python :)
Gandalf Saxe
1
Sebagai fyi untuk pembaca masa depan seperti saya: jika Anda tidak peduli untuk mengontrol jumlah digit dan tidak keberatan floating kesalahan titik, Anda dapat hanya menggunakan {num:E}, di mana misalnya num = 40800000000,00000000000000
Shayaan
4

Desimal saya terlalu besar untuk %Ejadi saya harus berimprovisasi:

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)

Berikut ini contoh penggunaannya:

>>> n = decimal.Decimal(4.3) ** 12314
>>> print format_decimal(n)
3.39e7800
>>> print '%e' % n
inf
ubershmekel
sumber
3
Hanya "{:.2e}".format(n)kembali '3.39e+7800'dengan Python 3.3.2 (v3.3.2: d047928ae3f6, 16 Mei 2013, 00:06:53) [MSC v.1600 64 bit (AMD64)] di win32.
Cees Timmerman
4

Ini bekerja paling baik untuk saya:

import decimal
'%.2E' % decimal.Decimal('40800000000.00000000000000')
# 4.08E+10
Matthew Fitch
sumber
4

Ini adalah daftar gabungan dari Jawaban & Komentar "Sederhana" .

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

Perbandingan

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

Jadi untuk Python 3, Anda dapat beralih di antara ketiganya untuk saat ini.

Favoritku:

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

Saya lebih suka cara Python 3.x.

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

4 menunjukkan berapa banyak digit yang ditampilkan pada bagian mengambang.

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

Untuk mengkonversi Desimal menjadi notasi ilmiah tanpa perlu menentukan ketepatan dalam string format, dan tanpa menyertakan nol tambahan, saya saat ini menggunakan

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

Untuk menjaga angka nol yang tertinggal, cukup hapus normalize().

MikeM
sumber
1

Ini adalah yang paling sederhana yang bisa saya temukan.

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

('E' tidak peka huruf besar-kecil. Anda juga dapat menggunakan '.2e')

Rahat Ibrahim
sumber
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
sumber