Python 如何用Decimal 实现货币四舍五入

需要用到精确计算。搜索了些文档,Decimal可以做精确的四舍五入,但发现 14.985这个数竟然不正确,不知道是bug还是我的误用。

Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from decimal import Decimal, ROUND_HALF_EVEN
>>> Decimal('14.985').quantize(Decimal('.01'), rounding=ROUND_HALF_EVEN)
Decimal('14.98')
>>> round(Decimal('14.985'),2)
Decimal('14.98')
>>> round(Decimal('3.675'),2)
Decimal('3.68')

环境:Python 3.8.8 (tags/v3.8.8:024d805, Feb 19 2021, 13:18:16) [MSC v.1928 64 bit (AMD64)] on win32

getcontext() 的输出默认。 Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[InvalidOperation, DivisionByZero, Overflow])

用ROUND_HALF_UP吧,ROUND_HALF_EVEN其实是银行家舍入法,查一下就知道了

In [18]: Decimal(‘14.984’).quantize(Decimal(‘0.00’), rounding=decimal.ROUND_HALF_EVEN) # 4舍 Out[18]: Decimal(‘14.98’)

In [19]: Decimal(‘14.986’).quantize(Decimal(‘0.00’), rounding=decimal.ROUND_HALF_EVEN) # 6入 Out[19]: Decimal(‘14.99’)

In [20]: Decimal(‘14.9851’).quantize(Decimal(‘0.00’), rounding=decimal.ROUND_HALF_EVEN) # 5后有有效数,舍5入1 Out[20]: Decimal(‘14.99’)

In [21]: Decimal(‘14.985’).quantize(Decimal(‘0.00’), rounding=decimal.ROUND_HALF_EVEN) # 5后无有效数,5前为偶数,舍5不入 Out[21]: Decimal(‘14.98’)

In [22]: Decimal(‘14.975’).quantize(Decimal(‘0.00’), rounding=decimal.ROUND_HALF_EVEN) # 5后无有效数,5前为奇数,舍5入1 Out[22]: Decimal(‘14.98’)

2 个赞

国内银行采用的是单纯四舍五入吧?我就想要单纯的四舍五入。