Точность задает количество значащих цифр, которое не эквивалентно количеству цифр после десятичной точки.
Так, если у вас есть точность 2, у вас будет две значащие цифры, поэтомучисло с 3 значащими цифрами, такими как 40.1
, будет уменьшено до двух верхних значащих цифр, давая 40
.
Нет простого способа установить количество цифр после десятичной точки с помощью Decimal
.Однако вы можете использовать высокую точность и всегда round
свои результаты с точностью до двух десятичных дробей:
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 60 # use a higher/lower one if needed
>>> Decimal('200') - Decimal('159.9')
Decimal('40.1')
>>> r = Decimal('200') - Decimal('159.9')
>>> round(r, 2)
Decimal('40.10')
Десятичный раздел FAQ также включает в себя аналогичный вопрос и ответ (используя quantize
):
Q.В приложении с фиксированной запятой с двумя десятичными знаками некоторые входные данные имеют много мест и должны быть округлены.Другие не должны иметь избыточных цифр и должны быть проверены.Какие методы следует использовать?
A.Метод quantize () округляет до фиксированного числа десятичных разрядов.Если установлена неточная ловушка, она также полезна для проверки:
>>> TWOPLACES = Decimal(10) ** -2 # same as Decimal('0.01')
>>> # Round to two places
>>> Decimal('3.214').quantize(TWOPLACES)
Decimal('3.21')
>>> # Validate that a number does not exceed two places
>>> Decimal('3.21').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Decimal('3.21')
>>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact]))
Traceback (most recent call last):
...
Inexact: None
Q.Как только я получу действительные двухместные входные данные, как мне сохранить этот инвариант в приложении?
A.Некоторые операции, такие как сложение, вычитание и умножение на целое число, автоматически сохраняют фиксированную точку.Другие операции, такие как деление и нецелочисленное умножение, изменят количество десятичных разрядов, и после них необходимо выполнить шаг quantize ():
>>> a = Decimal('102.72') # Initial fixed-point values
>>> b = Decimal('3.17')
>>> a + b # Addition preserves fixed-point
Decimal('105.89')
>>> a - b
Decimal('99.55')
>>> a * 42 # So does integer multiplication
Decimal('4314.24')
>>> (a * b).quantize(TWOPLACES) # Must quantize non-integer multiplication
Decimal('325.62')
>>> (b / a).quantize(TWOPLACES) # And quantize division
Decimal('0.03')
При разработке приложений с фиксированной запятой этоудобно определять функции для обработки шага quantize ():
>>> def mul(x, y, fp=TWOPLACES):
... return (x * y).quantize(fp)
>>> def div(x, y, fp=TWOPLACES):
... return (x / y).quantize(fp)
>>> mul(a, b) # Automatically preserve fixed-point
Decimal('325.62')
>>> div(b, a)
Decimal('0.03')