在我的程序中,十进制精度是非常重要的。
我的许多计算必须精确到小数点(例如50位)。
因为我使用的是python,所以我一直在使用十进制模块(带有context().prec = 99 )。当实例化一个十进制对象时,设置为有99小数位的精度)
因为丙酮浮子不允许任何接近这样的精确度。
由于我希望用户指定精确计算的小数位,所以我不得不在代码中实现几个循环()函数。
不幸的是,内置的圆函数和十进制对象并不能很好地相互作用。
round(decimal.Decimal('2.000000000000000000001'),50)
# Number is 1e-21. There are 21 decimal places, much less than 50.
然而,结果是2.0而不是
圆函数不舍入到50。更别说了!
是的,我已经确保过四舍五入不是在实例化Decimal对象时发生的,而是在调用循环之后发生的。
我总是将表示浮点的字符串传递给Decimal构造函数,而不是pythonic浮点数。
为什么圆函数要这样对我?
(我意识到它可能最初是为pythonic浮标设计的,它永远不会有如此多的小数位,但是文档声称十进制对象完美地集成到python代码中,并且与内置的python函数兼容!)
非常感谢!
(这让我相当不安,因为这个问题破坏了整个程序的使用)
规格:
python 2.7.1
Windows 7
十进制模块(内置)
发布于 2012-01-15 02:55:56
据我所知,问题是round()
返回的是Python float
类型,而不是Decimal
类型。因此,在decimal
模块上设置多高的精度并不重要,因为一旦调用round()
,就不再有Decimal
。
要解决这个问题,您可能需要想出一种不依赖round()
的替代方法来绕过您的数字。比如雷蒙德的建议。
你可能会发现这个简短的想法--一个例子说明:http://ideone.com/xgPL9
发布于 2012-01-15 02:33:45
由于http://docs.python.org/library/functions.html#round强制它的输入到一个常规二进制浮点数,所以循环十进制对象的首选方法是使用http://docs.python.org/library/decimal.html#decimal.Decimal.quantize方法:
>>> from decimal import Decimal
>>> d = Decimal('2.000000000000000000001')
>>> d.quantize(Decimal(10) ** -20) # Round to twenty decimal places
Decimal('2.00000000000000000000')
若要砍掉尾随零点,请将http://docs.python.org/library/decimal.html#decimal.Decimal.normalize应用于舍入结果:
>>> d = Decimal('2.000000000000000000001')
>>> d.quantize(Decimal(10) ** -20).normalize()
Decimal('2')
发布于 2013-02-27 10:54:36
试试下面的..。
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)
希望这能帮上忙!
https://stackoverflow.com/questions/8868985
复制相似问题