Ant*_*rth 22 python decimal rounding
在我的程序中,十进制精度非常重要.
我的很多计算必须精确到许多小数位(例如50).
因为我正在使用python,所以我一直在使用十进制模块(使用context().prec = 99. ie; 设置为在实例化十进制对象时具有99位小数的精确度)
因为pythonic浮点数不允许接近这样的精度.
由于我希望用户指定计算精度的小数位,我必须在我的代码中实现几个round()函数.
不幸的是,内置的圆函数和小数对象不能很好地相互作用.
round(decimal.Decimal('2.000000000000000000001'),50)
# Number is 1e-21. There are 21 decimal places, much less than 50.
Run Code Online (Sandbox Code Playgroud)
然而结果是2.0而不是2.000000000000000000001
圆函数没有四舍五入到50.更少!
是的,我已经确保在Decimal对象的实例化时不会发生过度舍入,但是在调用round之后.
我总是将表示浮点数的字符串传递给Decimal构造函数,而不是pythonic浮点数.
为什么圆函数对我这样做?
(我意识到它可能最初设计用于pythonic浮点数,它永远不会有这么多的小数位,但是文档声称Decimal对象完美地集成到python代码中并且与内置的python函数兼容!)
非常感谢!
(这让我非常不安,因为这个问题破坏了整个程序的使用)
规格:
python 2.7.1
Windows 7
十进制模块(内置)
Ray*_*ger 40
由于round()将其输入强制转换为常规二进制浮点数,因此舍入小数对象的首选方法是使用quantize()方法:
>>> from decimal import Decimal
>>> d = Decimal('2.000000000000000000001')
>>> d.quantize(Decimal(10) ** -20) # Round to twenty decimal places
Decimal('2.00000000000000000000')
Run Code Online (Sandbox Code Playgroud)
要删除尾随零,请将normalize()应用于舍入结果:
>>> d = Decimal('2.000000000000000000001')
>>> d.quantize(Decimal(10) ** -20).normalize()
Decimal('2')
Run Code Online (Sandbox Code Playgroud)
尝试以下...
from decimal import Decimal, ROUND_HALF_UP, getcontext
getcontext().prec = 51
def round_as_decimal(num, decimal_places=2):
"""Round a number to a given precision and return as a Decimal
Arguments:
:param num: number
:type num: int, float, decimal, or str
:returns: Rounded Decimal
:rtype: decimal.Decimal
"""
precision = '1.{places}'.format(places='0' * decimal_places)
return Decimal(str(num)).quantize(Decimal(precision), rounding=ROUND_HALF_UP)
round_as_decimal('2.000000000000000000001', decimal_places=50)
Run Code Online (Sandbox Code Playgroud)
希望有帮助!
| 归档时间: |
|
| 查看次数: |
19961 次 |
| 最近记录: |