python 3.7 和 Django 中金额的前 2 位小数舍入错误

Wrong decimal round to first 2 digits of amounts in python 3.7 and Django

假设有 3 个 Django 字段:

    INPUT   = models.DecimalField(max_digits=20, decimal_places=3, default=0)
    RESULT  = models.DecimalField(max_digits=20, decimal_places=3, default=0)
    RATE    = models.DecimalField(max_digits=12, decimal_places=5, default=1)

RATE 总是 Decimal('1.00000').

我想要 RESULT = INPUT * RATE 并且由于来源要么来自数据库,要么来自 API,我使用:

RESULT = Decimal(INPUT) * Decimal(RATE)

我不知道为什么,但在某些情况下 (≈ 2%) 我以您在下面看到的数字结尾 table。前2位有舍入。

你知道是什么原因造成的吗?我在代码中看不到任何可以做到这一点的东西,而且我一无所知。 两列应该相等。

  RESULT    INPUT    
 610.000    609.000 
3700.000    3743.520
1200.000    1159.000
 570.000    573.300
  61.000    61.470
1300.000    1321.550
  44.000    43.730
 130.000    125.770
  18.000    18.500
 100.000    99.590
  41.000    40.650
  95.000    94.880
  19.000    18.710
  36.000    35.640
 120.000    118.800
  12.000    12.290
  11.000    11.260
   1.000    1.030
 160.000    155.970
 190.000    186.850
  51.000    50.770
 130.000    128.150
  12.000    12.290
  11.000    11.260
  25.000    24.940
  24.000    23.640

看来是小数上下文精度的原因:

getcontext().prec = 2

在代码的某处,它已被设置,并且永远不会重置。这是精度为 2 时发生的情况:

>>> import decimal
>>> decimal.getcontext()
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[InvalidOperation, Inexact, FloatOperation, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])

>>> decimal.getcontext().prec = 2
>>> decimal.getcontext()
Context(prec=2, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[InvalidOperation, Inexact, FloatOperation, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])

>>> Decimal(3.21)
Decimal('3.20999999999999996447286321199499070644378662109375')
>>> Decimal(3.21) * Decimal(1)
Decimal('3.2')

>>> Decimal(58341)
Decimal('58341')
>>> Decimal(58341) * Decimal(1)
Decimal('5.8E+4')