Преобразование поплавка в строку без округления - PullRequest
80 голосов
/ 23 августа 2009

Я делаю программу, которая по причинам, не нуждающимся в объяснении, требует преобразования числа с плавающей запятой в строку для подсчета с помощью len (). Однако, str (float (x)) приводит к округлению x при преобразовании в строку, которая отбрасывает всю вещь. Кто-нибудь знает, как это исправить? Вот код, который используется, если вы хотите знать:

len(str(float(x)/3))

Ответы [ 4 ]

119 голосов
/ 23 августа 2009

Некоторая форма округления часто неизбежна при работе с числами с плавающей запятой. Это связано с тем, что числа, которые вы можете выразить точно в базе 10, не всегда могут быть точно выражены в базе 2 (которую использует ваш компьютер).

Например:

>>> .1
0.10000000000000001

В этом случае вы видите .1 преобразованный в строку, используя repr:

>>> repr(.1)
'0.10000000000000001'

Я полагаю, что python отсекает последние несколько цифр, когда вы используете str () для решения этой проблемы, но это частичный обходной путь, который не заменяет понимание того, что происходит.

>>> str(.1)
'0.1'

Я не совсем уверен, какие проблемы вызывает "округление". Возможно, вам лучше использовать форматирование строк, чтобы более точно контролировать вывод?

, например

>>> '%.5f' % .1
'0.10000'
>>> '%.5f' % .12345678
'0.12346'

Документация здесь .

11 голосов
/ 23 августа 2009
len(repr(float(x)/3))

Однако я должен сказать, что это не так надежно, как вы думаете.

Плавания вводятся / отображаются в виде десятичных чисел, но ваш компьютер (фактически, ваша стандартная библиотека C) хранит их как двоичные. Вы получаете некоторые побочные эффекты от этого перехода:

>>> print len(repr(0.1))
19
>>> print repr(0.1)
0.10000000000000001

Объяснение того, почему это происходит, содержится в этой главе руководства по питону.

Решением было бы использование типа, который специально отслеживает десятичные числа, например, Python decimal.Decimal:

>>> print len(str(decimal.Decimal('0.1')))
3
3 голосов
/ 23 августа 2009

В других ответах уже указывалось, что представление плавающих чисел является, по меньшей мере, сложной задачей.

Поскольку в вашем вопросе недостаточно контекста, я не знаю, может ли десятичный модуль быть полезным для ваших нужд:

http://docs.python.org/library/decimal.html

Среди прочего вы можете явно указать точность, которую вы хотите получить (из документации):

>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')

Простой пример из моей подсказки (python 2.6):

>>> import decimal
>>> a = decimal.Decimal('10.000000001')
>>> a
Decimal('10.000000001')
>>> print a
10.000000001
>>> b = decimal.Decimal('10.00000000000000000000000000900000002')
>>> print b
10.00000000000000000000000000900000002
>>> print str(b)
10.00000000000000000000000000900000002
>>> len(str(b/decimal.Decimal('3.0')))
29

Может быть, это может помочь? decimal находится в python stdlib начиная с 2.4, с дополнениями в python 2.6.

Надеюсь, это поможет, Francesco

0 голосов
/ 17 июля 2018

Я знаю, что уже слишком поздно, но для тех, кто приезжает сюда впервые, я хотел бы опубликовать решение. У меня есть значение с плавающей точкой index и строка imgfile, и у меня была такая же проблема, как у вас. Так я исправил проблему

index = 1.0
imgfile = 'data/2.jpg'
out = '%.1f,%s' % (index,imgfile)
print out

Выход

1.0,data/2.jpg

Вы можете изменить этот пример форматирования по вашему усмотрению.

...