Python3 .8. Round с десятичным конструктором с плавающей запятой или строкой - PullRequest
0 голосов
/ 24 апреля 2020

Я сталкиваюсь со странным поведением при работе с python десятичным модулем

Пример ниже:

print(round(Decimal('0.005'),2))
>>> Decimal('0.00')
print(round(Decimal(0.005),2))
>>> Decimal('0.01')


print(round(Decimal('0.006'),2))
>>> Decimal('0.01')
print(round(Decimal(0.006),2))
>>> Decimal('0.01')

Может кто-нибудь объяснить, почему это происходит и как я могу преобразовать Decimal('0.005') в Decimal(0.005)

1 Ответ

1 голос
/ 24 апреля 2020

Вы заметили, что представление с плавающей запятой десятичных цифр

>>> Decimal(0.005) 
Decimal('0.005000000000000000104083408558608425664715468883514404296875')

равно ли это 0,005?

>>> 0.005 == 0.005000000000000000104083408558608425664715468883514404296875
True

На этапе округления, так как значение>> 1007 * округляется до 0.01.

Это ожидаемое поведение.

как я могу преобразовать десятичную ('0,005') в десятичную (0,005)

>>> round(Decimal(float('0.005')), 2)
Decimal('0.01')

Однако, это, вероятно, не то, что вы хотите. мне кажется, что *1018* уместно было бы точно преобразовать ваши входные данные в десятичную, а затем явно применить стратегию округления.

Чтобы преобразовать входные данные с плавающей запятой в Десятичное число

Есть несколько вариантов.

  1. Применить str ваш ввод

    >>> Decimal(str(0.005)) == Decimal(str('0.005'))
    True
    
  2. quantize после преобразования числа с плавающей запятой в десятичное. Квантование также позволяет округлять и указывать точный метод округления. Обратите внимание, что здесь я не округляю с помощью метода квантования (этот пример ниже). Здесь я указываю то же количество цифр, что и для ввода.

    >>> Decimal(0.005).quantize(Decimal('1.000'))
    Decimal('0.005')
    

Для округления вы можете вызвать round для объекта Decimal, как вы это сделали. Или вы можете использовать Decimal.quantize метод

Decimal(0.005).quantize(Decimal('1.00'), rounding=<ROUNDING_METHOD>)

, где доступные ROUNDING_METHOD найдены в документации для десятичного модуля

Если вы хотите Decimal(0.005) чтобы всегда округляться, затем укажите ROUND_HALF_UP. Однако обратите внимание, что python 3 по умолчанию использует округление ROUND_HALF_EVEN (также называемое банковским округлением), и поэтому round(Decimal('0.005'), 2) выводит 0.00

...