Visualizza un decimale in notazione scientifica


161

Come posso visualizzare questo:

Decimale ('40800000000.00000000000000') come '4.08E + 10'?

Ho provato questo:

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

Ma ha quegli 0 in più.


3
un po 'doppio posting, avresti potuto usare questo argomento che hai appena iniziato: stackoverflow.com/questions/6913166/…
Samuele Mattiuzzo

13
nah, per niente. Volevo separarlo dalla domanda semplice (come farlo in Python) e dalla domanda difficile e oscura a cui dubito che qualcuno risponderà (come farlo in Django). Nota come questo ha già una risposta. Sono ora a metà della mia risposta finale invece dello 0% se le avessi postate insieme. Oltre a ciò, separare le domande rende più facile per le persone cercare le risposte. Ad esempio, se Bob sta cercando una domanda di formattazione decimale, potrebbe saltare una quest SO con Django nel titolo.
Greg,

sì, era solo per il mio interesse: P è più facile seguire un thread. in fondo è simile alla mia risposta (solo un po 'più specifica). spero anche una risposta da django, tra l'altro.
Samuele Mattiuzzo il

Risposte:


157
from decimal import Decimal

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

# returns '4.08E+10'

Nel "40800000000.00000000000000" ci sono molti zeri più significativi che hanno lo stesso significato di qualsiasi altra cifra. Ecco perché devi dire esplicitamente dove vuoi fermarti.

Se desideri rimuovere automaticamente tutti gli zeri finali, puoi provare:

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
A parte questo, nonostante la format % valuessintassi sia ancora utilizzata anche all'interno della libreria standard di Python 3, credo che sia tecnicamente deprecata in Python 3, o almeno non il metodo di formattazione consigliato, e l'attuale sintassi consigliata, a partire da Python 2.6, sarebbe '{0:.2E}'.format(Decimal('40800000000.00000000000000'))( o '{:.2E}'in Python 2.7+). Sebbene non sia strettamente utile per questa situazione, a causa dei caratteri aggiuntivi per nessuna funzionalità aggiunta, str.formatconsente un mix / riorganizzazione / riutilizzo di argomenti di formato più complessi.
JAB,

che dire di python 3?
Charlie Parker,

4
@CharlieParker Use format. È più jazz .
Mateen Ulhaq,


37

Dato il tuo numero

x = Decimal('40800000000.00000000000000')

A partire da Python 3,

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

è il modo consigliato per farlo.

esignifica che vuoi una notazione scientifica e .2vuoi 2 cifre dopo il punto. Quindi otterraix.xxE±n


1
Il punto di usare Decimale è ottenere l'aritmetica decimale di precisione esatta e arbitraria. Non è equivalente all'utilizzo di un float.
asmeurer,

@asmeurer Grazie per il chiarimento. Ho cambiato la mia risposta.
patapouf_ai,

C'è un modo per tornare da questo a galleggiare?
olenscki,

@olenscki semplicemente facendo float(x)convertirà x in float.
patapouf_ai

33

Nessuno ha menzionato la forma abbreviata del .formatmetodo:

Richiede almeno Python 3.6

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

(Credo che sia lo stesso di Cees Timmerman, solo un po 'più corto)


3
Dovrebbe essere accettata la risposta. f-string è il futuro della formattazione delle stringhe di pitone :)
Gandalf Saxe,

1
Come un amico per i futuri lettori come me: se non ti interessa controllare il numero di cifre e non ti dispiace gli errori in virgola mobile, puoi semplicemente utilizzare {num:E}, dove ad esempio num = 40800000000.00000000000000
Shayaan,


4

I miei decimali sono troppo grandi per %Ecui ho dovuto improvvisare:

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)

Ecco un esempio di utilizzo:

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

3
Appena "{:.2e}".format(n)torna '3.39e+7800'in Python 3.3.2 (V3.3.2: d047928ae3f6 16 maggio 2013, 00:06:53) [MSC v.1600 64 bit (AMD64)] su win32.
Cees Timmerman,

4

Questo ha funzionato meglio per me:

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

4

Questa è una lista consolidata del "Semplice" risposte e dei commenti .

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

O Senza IMPORTs'

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

confrontando

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

Quindi per Python 3, per il momento puoi passare da uno qualsiasi dei tre.

Il mio preferito:

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

3

Preferisco il modo Python 3.x.

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

4 indica quante cifre sono mostrate mostrate nella parte mobile.

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

2

Per convertire una notazione decimale in notazione scientifica senza la necessità di specificare la precisione nella stringa di formato e senza includere zeri finali, sto attualmente utilizzando

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

Per mantenere eventuali zeri finali, basta rimuovere il normalize().


1

Ecco il più semplice che ho trovato.

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

('E' non fa distinzione tra maiuscole e minuscole. Puoi anche usare '.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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.