Pergunta

Python Decimal não suporta a ser construído a partir de flutuador; Espera-se que você tem que converter float para uma string em primeiro lugar.

Este é muito inconveniente desde formatadores de cordas padrão para flutuador exigem que você especifique o número de casas decimais em vez de lugares significativos. Então se você tem um número que pode ter até 15 casas decimais que você precisa para o formato como Decimal ( "" %. 15f "% my_float), que lhe dará o lixo no local 15 decimal se você também tem nenhum dígitos significativos antes decimal.

Alguém pode sugerir uma boa maneira de converter de float para Decimal valor preservar como o usuário entrou, talvez limitando o número de dígitos significativos que podem ser apoiados?

Foi útil?

Solução

Python <2.7

"%.15g" % f

Ou no Python 3.0:

format(f, ".15g")

Python 2.7+, 3,2 +

Basta passar o flutuador ao construtor Decimal diretamente, como este:

from decimal import Decimal
Decimal(f)

Outras dicas

Você disse em sua pergunta:

Alguém pode sugerir uma boa maneira de converter de float para Decimal valor preservar como o usuário tem entrou

Mas cada vez que o usuário digita um valor, é introduzido como uma cadeia, não como um float. Você está convertê-lo para um lugar float. Convertê-lo para um Decimal diretamente em vez e não há precisão serão perdidas.

Eu sugiro que esta

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

Python suporta criação Decimal de um float. Você só lançá-lo como uma string em primeiro lugar. Mas a perda de precisão não ocorre com a conversão de string. O flutuador está a converter não tem esse tipo de precisão em primeiro lugar. (Caso contrário, você não precisaria Decimal)

Eu acho que a confusão aqui é que podemos criar literais flutuar no formato decimal , mas assim que os consome intérprete que literal a representação interna torna-se um número de ponto flutuante.

A representação "oficial" de cadeia de um flutuador é dada pela repr () built-in:

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

Você pode usar repr () em vez de uma string formatada, o resultado não conterá qualquer lixo desnecessário.

Quando você diz "preservar o valor que o usuário entrou", porque não basta armazenar o valor inserido pelo usuário como uma string, e passar isso para o construtor Decimal?

A maneira "certa" de fazer isso foi documentado em 1990 por Steele e Areia Branca PLDI 1990 papéis de Clinger.

Você também pode olhar para esta discussão SO sobre Python Decimal, incluindo minha sugestão para tentar usar algo como frap para racionalizar um float.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top