Чтение числа из строки - PullRequest
       29

Чтение числа из строки

1 голос
/ 22 сентября 2009

У меня есть простая строка, которую я хочу прочитать в число с плавающей точкой, не теряя никакой видимой информации, как показано ниже:

s = '      1.0000\n'

Когда я делаю f = float(s), я получаю f=1.0

Как обмануть это, чтобы получить f=1.0000?

Спасибо

Ответы [ 4 ]

9 голосов
/ 22 сентября 2009

Прямой ответ : Вы не можете. Поплавки неточные, по дизайну. Хотя у поплавков python более чем достаточно точности для представления 1.0000, они никогда не будут представлять "1-точку-ноль-ноль-ноль-ноль". Скорее всего, это так хорошо, как вам нужно. Вы всегда можете использовать форматирование строки, если вам нужно отобразить четыре десятичных знака.

print '%.3f' % float(1.0000)

Косвенный ответ : Используйте модуль decimal.

from decimal import Decimal
d = Decimal('1.0000')

Пакет decimal предназначен для решения всех этих проблем с произвольной точностью. Десятичное число «1,0000» равно точно 1,0000, не больше, не меньше. Однако обратите внимание, что сложности с округлением означают, что вы не можете конвертировать из float напрямую в Decimal; Вы должны передать строку (или целое число) конструктору.

5 голосов
/ 22 сентября 2009
>>> 1.0 == 1.00 == 1.000
True

Другими словами, вы не теряете информацию - Python считает, что конечные нули в десятичных частях числа с плавающей точкой не имеют значения. Если вам нужно очень точно отслеживать «количество значащих цифр», это также выполнимо, но вам необходимо объяснить нам всем, что именно вы пытаетесь достичь, помимо обычного float в Python (например, decimal в стандартной библиотеке Python какое-либо отношение к этому? и т. д., и т. д.).

1 голос
/ 22 сентября 2009

Вот еще более блестящая версия @Simon Edwards 'ExactFloat, которая подсчитывает количество цифр после периода и отображает это количество цифр при преобразовании числа в строку.

import re

class ExactFloat(float):
    def __init__(self, str_value):
        float.__init__(self, str_value)
        mo = re.match("^\d+\.(\d+)", str_value)
        self.digits_after_period = len(mo.group(1))

    def __repr__(self):
        return '%.*f' % (self.digits_after_period, self)

    def __str__(self):
        return self.__repr__()


print ExactFloat("1.000")
print ExactFloat("1.0")
print ExactFloat("23.234500")

Пример:

$ python exactfloat.py
1.000
1.0
23.234500
1 голос
/ 22 сентября 2009

Побалуйте меня, пока я заново изобрету колесо! ;)

Если вы хотите, чтобы значение repr объекта (как оно отображается в оболочке) имело форму 1.0000, то вам может потребоваться изменить метод __repr__ для float. Если вы хотите, чтобы объект был напечатан в файл или на экран, вам нужно изменить метод __str__. Вот класс, который будет делать оба.

class ExactFloat(float):
    def __repr__(self):
        return '%.4f' % self
    __str__ = __repr__


# usage of the shiny new class to follow..
>>> f = ExactFloat('    1.0000\n')
>>> f
1.0000
>>> print f
1.0000

Теперь есть также множество других better способов сделать это, но, как я уже сказал, я люблю заново изобретать колеса :)

...