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.


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'

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'

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


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)


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

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

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

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} ")

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


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


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.