【问题标题】:python decimal precision and django DecimalFieldpython小数精度和django DecimalField
【发布时间】:2016-11-17 23:03:19
【问题描述】:

为什么我在这里得到错误的精度?我在浮点数之后询问了 3 个十进制数字。

>>> from decimal import Decimal
>>> from decimal import getcontext

>>> getcontext().prec = 3
>>> Decimal(1.111) + Decimal(2.222)
Decimal('3.33') # Why not 3.333?

第二个问题,对于 django DecimalField,我这样定义我的字段:

value = models.DecimalField(max_digits=10, decimal_places=3)

它是否给出与设置相同的结果

getcontext().prec = 3

十进制?

【问题讨论】:

    标签: python django floating-point decimal rounding


    【解决方案1】:
    1. prec 设置充当max_digits 设置,因此如果您尝试将 200.222 和 300.333 的小数相加,您会立即看到问题。要获得精确的 3 位小数,您可以使用 round() 函数,例如 round(Decimal(123.3334343), 3)

    2. 该问题实际上已在第一部分回答,但只是为了澄清:
      max_digits 设置逗号前后总共可以有多少位数。
      decimal_places 指定存储了多少位小数。
      因此,简短的回答是否定的:getcontext().prec = 3 != decimal_places=3

    【讨论】:

    • 所以 max_digits 就像 getcontext().prec?如果是这样,如何使用小数模块控制小数位(逗号后的位数)?即 django 做了什么来确保小数位?
    • @user3599803 我检查了源代码,Django (1.9) 使用django.db.backends.utils.format_number 函数,定义为format_number(value, max_digits, decimal_places),但它返回一个字符串,因为我认为(不是事实,意见。如果你查一下,让我知道)十进制作为字符串存储在数据库中。
    • 实际上在我的数据库 - MySQL 中,小数点存储为 DECIMAL(10, 3) 数据类型。所以至少这里不是一个字符串。无论如何,我还是看看如何配置十进制对象decimal_places。如果有办法当然
    • @user3599803 好吧,您可以直接从字符串生成小数(Decimal("1.123") 有效),所以如果您愿意,您仍然可以使用 Django util 函数。但这似乎有点矫枉过正,我会选择round()
    • 据我所知,round 不是 Decimal 的最佳选择,最好使用 quantize docs.python.org/3.8/library/…
    猜你喜欢
    • 1970-01-01
    • 2018-10-19
    • 2014-02-08
    • 2013-07-17
    • 2022-12-11
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    相关资源
    最近更新 更多