Значимые цифры в десятичном модуле - PullRequest
5 голосов
/ 27 сентября 2008

Итак, я решил попытаться решить домашнее задание по физике, написав несколько сценариев на python, чтобы решить проблемы для меня. Одна проблема, с которой я сталкиваюсь, заключается в том, что значимые цифры не всегда выглядят правильно. Например, это правильно обрабатывает значимые цифры:

from decimal import Decimal
>>> Decimal('1.0') + Decimal('2.0')
Decimal("3.0")

Но это не так:

>>> Decimal('1.00') / Decimal('3.00')
Decimal("0.3333333333333333333333333333")

Итак, два вопроса:

  1. Прав ли я, что это не ожидаемое количество значащих цифр, или мне нужно освежить в математике значащие цифры?
  2. Есть ли способ сделать это, не устанавливая десятичную точность вручную? Конечно, я уверен, что могу использовать numpy для этого, но я просто хочу знать, есть ли способ сделать это с десятичным модулем из любопытства.

Ответы [ 6 ]

8 голосов
/ 28 сентября 2008

Изменение десятичной рабочей точности на 2 цифры не хорошая идея, если только вы не собираетесь выполнять только одну операцию.

Вы всегда должны выполнять вычисления с более высокой точностью, чем уровень значимости, и только вокруг конечного результата. Если вы выполняете длинную последовательность вычислений и округляете количество значащих цифр на каждом шаге, ошибки будут накапливаться. Десятичный модуль не знает, выполняется ли какая-либо конкретная операция в длинной последовательности или конечный результат, поэтому он предполагает, что он не должен округляться больше, чем необходимо. В идеале он будет использовать бесконечную точность, но это слишком дорого, поэтому разработчики Python согласились на 28 цифр.

Как только вы достигнете конечного результата, вам, вероятно, понадобится квантовать:

>>> (Decimal('1.00') / Decimal('3.00')).quantize(Decimal("0.001"))
Decimal("0.333")

Вы должны отслеживать значимость вручную. Если вы хотите автоматическое отслеживание значимости, вы должны использовать интервальную арифметику. Для Python доступны некоторые библиотеки, включая pyinterval и mpmath (который поддерживает произвольную точность). Также легко реализовать интервальную арифметику с десятичной библиотекой, поскольку она поддерживает направленное округление.

Возможно, вы также захотите прочитать FAQ по десятичной арифметике: арифметика десятичных чисел - "значимость"?

3 голосов
/ 27 сентября 2008

Десятичные дроби не выбрасывают такие десятичные знаки. Если вы действительно хотите ограничить точность до 2 д.п. тогда попробуйте

decimal.getcontext().prec=2

РЕДАКТИРОВАТЬ: Вы также можете вызывать quantize () каждый раз, когда вы умножаете или делите (сложение и вычитание сохранят 2 dps).

1 голос
/ 05 апреля 2009

Просто из любопытства ... нужно ли использовать десятичный модуль? Почему бы не с плавающей точкой с округлением чисел в значащие цифры, когда вы готовы их увидеть? Или вы пытаетесь отслеживать значимые цифры вычислений (например, когда вам нужно выполнить анализ ошибок результата, вычисляя вычисленную ошибку как функцию неопределенностей, которые вошли в расчет)? Если вам нужна функция округления, которая округляет число слева, а не справа, попробуйте:

def lround(x,leadingDigits=0): 
    """Return x either as 'print' would show it (the default) 
    or rounded to the specified digit as counted from the leftmost 
    non-zero digit of the number, e.g. lround(0.00326,2) --> 0.0033
    """ 
    assert leadingDigits>=0 
    if leadingDigits==0: 
            return float(str(x)) #just give it back like 'print' would give it
    return float('%.*e' % (int(leadingDigits),x)) #give it back as rounded by the %e format  

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

>>> lround(1./3.,2),str(lround(1./3.,2)),str(lround(1./3.,4))
(0.33000000000000002, '0.33', '0.3333')
0 голосов
/ 27 сентября 2008

Что не так с плавающей точкой?

>>> "%8.2e"%  ( 1.0/3.0 )
'3.33e-01'

Он был разработан для расчетов в научном стиле с ограниченным количеством значащих цифр.

0 голосов
/ 27 сентября 2008

Если я правильно введу десятичное число, «точность» - это число цифр после десятичной точки в десятичной записи .

Кажется, вы хотите что-то еще: количество значащих цифр. Это на одну единицу больше, чем число цифр после десятичной точки в научной записи .

Мне было бы интересно узнать о модуле Python, который выполняет вычисления с плавающей запятой с учетом значащих цифр.

0 голосов
/ 27 сентября 2008

Десятичное значение по умолчанию до 28 мест точности.
Единственный способ ограничить количество возвращаемых цифр - изменить точность.

...