Хобрук: Ваш путь к мастерству в программировании

Почему getcontext().prec = 2 на самом деле не устанавливает его так, чтобы использование Decimal() соответствовало двум десятичным знакам?

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

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

from decimal import *
getcontext().prec = 2
test = Decimal(5.859)
print(test)

Я ожидал, что это напечатает вывод 5,86 или, в худшем случае, не менее 5,85, если он не округляется в нужном направлении.

Вместо этого он напечатал.

5.8589999999999999857891452847979962825775146484375

тот же вывод, как если бы getcontext().prec = 2 никогда не использовался

Пожалуйста, имейте в виду, что вы умеренно новичок в python, поэтому, пожалуйста, не предполагайте, что я точно буду знать, что вы имеете в виду, если вы бросите мне случайный код без объяснения причин.

10.06.2019

  • Начнем с того, что передача объекта с плавающей запятой конструктору Decimal это совсем не то, что вы имеете в виду. Весь пункт заключается в том, что объекты float по своей природе неточны.* поэтому у вас все еще будет эта неточность, если вы передадите число с плавающей запятой в Decimal*. В любом случае точность, о которой вы беспокоитесь, проявляется только во время арифметических операций. так что посмотрите, что произойдет, когда вы сделаете test + Decimal('0.00001'). затем измените точность и повторите попытку. 11.06.2019
  • Итак, из документов: значение новый Decimal определяется исключительно количеством введенных цифр. Точность контекста и округление вступают в игру только во время арифметических операций. Что может удивить. 11.06.2019
  • @juanpa.arrivillaga Отличные объяснения, хотя в +Decimal('0.00001') нет необходимости. Унарной операции + (то есть +test) было бы достаточно. 11.06.2019
  • @blhsing конечно, но это могло быть немного загадочно, я думаю, что приведенный выше пример немного более понятен 11.06.2019
  • @juanpa.arrivillaga Лично я считаю, что добавление произвольного ненулевого числа к предполагаемому числу будет более загадочным. Я бы просто сделал это test + Decimal(0), если кто-то предпочитает избегать использования унарной операции. 11.06.2019
  • @blhsing, это кажется разумным 11.06.2019
  • @juanpa.arrivillaga спасибо за информацию, информация, найденная в Интернете, использовала некоторые поплавки для своих примеров, поэтому я не думал, что это вызовет какие-либо проблемы. В реальном коде я использовал конструктор Decimal для некоторых чисел с плавающей запятой в списке, которые были переданы через сумму, чтобы получить их общее количество. Информация, найденная в Интернете, заставила меня поверить, что это сработает. Я исправил свой фактический код, объединив Decimal и Round, это может быть не вариант в некоторых ситуациях, но для моего фактического кода он выполнил свою работу. 11.06.2019
  • @ Джей, почему бы тебе просто не использовать строки? 11.06.2019
  • @ juanpa.arrivillaga это не сработает для того, что я хочу, чтобы программа делала, по крайней мере, насколько мне известно, что, как я признаю, означает, что скорее есть способ заставить ее работать, чем нет. 11.06.2019
  • Что ж, слушайте, чтобы правильно работать с денежными значениями, вы не можете использовать float. Если бы вы могли расширить свои ограничения, возможно, кто-то мог бы помочь вам решить эту проблему. 11.06.2019

Ответы:


1

Согласно этой документации, точность контекста и округление используются только во время арифметических операций. . Итак, чтобы достичь своей цели, вы можете сделать что-то вроде этого:

from decimal import *
getcontext().prec = 3
test = Decimal('5.859')/Decimal('1')
print(test)

выход:

Decimal('5.86')
10.06.2019
  • не передавайте поплавки конструктору Decimal! 11.06.2019
  • Также есть Context.create_decimal. 11.06.2019
  • Спасибо, тем временем я нашел обходной путь для самого фактического кода. 11.06.2019
  • Новые материалы

    Декларативное и функциональное программирование в стиле LINQ с использованием JavaScript с использованием каррирования и генератора ...
    LINQ - одна из лучших функций C #, которая обеспечивает элегантный способ написания кода декларативного и функционального стиля, который легко читать и понимать. Благодаря таким функциям ES6,..

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..

    Как я опубликовал свое первое приложение в App Store в 13 лет
    Как все началось Все началось три года назад летом после моего четвертого класса в начальной школе. Для меня, четвертого класса, лето кажется бесконечным, пока оно не закончится, и мой отец..

    Что в лицо
    Очерк о возвращении физиогномики и о том, почему мы должны это приветствовать. История начинается со странной науки. Р. Тора Бьорнсдоттир, Николас О. Рул. Видимость социального класса по..

    Почему шаблоны проектирования и почему нет?
    Сложность — мать всех проблем в программировании. Программное обеспечение должно быть разработано с точки зрения того, кто его поддерживает, а не того, кто его пишет, потому что программное..

    Создание дизайна обуви с помощью машинного обучения
    Обувь. Что подождать? Я думал, что речь пойдет о машинном обучении! Ну это так. Если бы вы пошли на Amazon, сколько обуви вы бы нашли? Наверное, много, не так ли? Но много ли в них..

    GraalVM в 2022 году: итоги года
    2022 год был очень продуктивным для проекта и сообщества GraalVM. Вместе мы разработали множество новых функций, выпустили GraalVM для последних версий Java и новых платформ и увидели несколько..