Преобразование float в строку без округления
Я делаю программу, которая по причинам, не требующим объяснения, требует, чтобы float преобразовывался в строку, которая должна быть подсчитана с помощью len(). Однако str (float (x)) приводит к округлению x при преобразовании в строку, что исключает все. Кто-нибудь знает об этом?
Здесь код используется, если вы хотите знать:
len(str(float(x)/3))
Ответы
Ответ 1
Некоторая форма округления часто неизбежна при работе с числами с плавающей запятой. Это связано с тем, что цифры, которые вы можете точно выразить в базе 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'
Документация здесь.
Ответ 2
len(repr(float(x)/3))
Однако я должен сказать, что это не так надежно, как вы думаете.
Поплавки вводятся/отображаются как десятичные числа, но ваш компьютер (фактически, ваша стандартная библиотека C) сохраняет их как двоичные. Вы получаете некоторые побочные эффекты от этого перехода:
>>> print len(repr(0.1))
19
>>> print repr(0.1)
0.10000000000000001
Объяснение, почему это происходит, находится в этой главе учебника python.
Решением будет использовать тип, который специально отслеживает десятичные числа, например python decimal.Decimal
:
>>> print len(str(decimal.Decimal('0.1')))
3
Ответ 3
Другие ответы уже указывали на то, что представление плавающих чисел является, по меньшей мере, сложной проблемой.
Поскольку в вашем вопросе недостаточно контекста, я не могу знать, может ли десятичный модуль быть полезным для ваших нужд:
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