Domanda

Python Decimal non supporta la costruzione da float; si aspetta che tu debba prima convertire float in una stringa.

Ciò è molto scomodo poiché i formattatori di stringhe standard per float richiedono che si specifichi il numero di posizioni decimali anziché posizioni significative. Quindi se hai un numero che può avere fino a 15 cifre decimali devi formattare come Decimale (& Quot; & Quot;%. 15f & Quot;% my_float), che ti darà immondizia in il 15o decimale se si hanno anche cifre significative prima del decimale.

Qualcuno può suggerire un buon modo per convertire da float a valore decimale preservando il valore immesso dall'utente, forse limitando il numero di cifre significative che possono essere supportate?

È stato utile?

Soluzione

Python < 2.7

"%.15g" % f

O in Python 3.0:

format(f, ".15g")

Python 2.7+, 3.2+

Basta passare il galleggiante direttamente al Decimal costruttore, in questo modo:

from decimal import Decimal
Decimal(f)

Altri suggerimenti

Hai detto nella tua domanda:

  

Qualcuno può suggerire un buon modo per   convertire da float a decimale    preservare il valore come ha l'utente   entrato

Ma ogni volta che l'utente immette un valore, questo viene inserito come stringa, non come float. Lo stai convertendo in un galleggiante da qualche parte. Convertire direttamente in un decimale invece e non si perderà alcuna precisione.

Suggerisco questo

>>> a = 2.111111
>>> a
2.1111110000000002
>>> str(a)
'2.111111'
>>> decimal.Decimal(str(a))
Decimal('2.111111')

Python supporta la creazione decimale da un float. L'hai appena lanciato come stringa. Ma la perdita di precisione non si verifica con la conversione di stringhe. Il float che stai convertendo non ha quel tipo di precisione in primo luogo. (Altrimenti non avresti bisogno del decimale)

Penso che la confusione qui sia che possiamo creare letterali float in formato decimale , ma non appena l'interprete consuma quel valore letterale, la rappresentazione interna diventa un numero in virgola mobile.

Il " ufficiale " la rappresentazione in forma di stringa di un float è data dal repr () incorporato:

>>> repr(1.5)
'1.5'
>>> repr(12345.678901234567890123456789)
'12345.678901234567'

Puoi usare repr () invece di una stringa formattata, il risultato non conterrà inutili immondizie.

Quando dici " preservare il valore quando l'utente ha inserito " ;, perché non archiviare semplicemente il valore immesso dall'utente come stringa e passarlo al costruttore Decimale?

Il " giusto " modo per farlo è stato documentato nel 1990 da Steele and White's e Articoli PLDI 1990 di Clinger .

Puoi anche guardare questa discussione SO su Python Decimal, tra cui il mio consiglio di provare a usare qualcosa come frap per razionalizzare un float.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top