在Python 2.5到2.7中,十进制除法结果无效
我仔细阅读了Python的decimal模块文档,但对于在进行小数除法时发生了什么,我还是感到困惑。
在Python 2.4.6中,结果是可以理解的:
>>> import decimal
>>> decimal.Decimal(1000) / 10
Decimal("100")
但是在Python 2.5.6、2.6.7和2.7.2中,结果就让人摸不着头脑了:
>>> import decimal
>>> decimal.Decimal(1000) / 10
Decimal('0.00000-6930898827444486144')
更让人困惑的是,这个结果看起来似乎都不正确:
>>> decimal.Decimal('0.00000-6930898827444486144')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/decimal.py", line 548, in __new__
"Invalid literal for Decimal: %r" % value)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/decimal.py", line 3844, in _raise_error
raise error(explanation)
decimal.InvalidOperation: Invalid literal for Decimal: '0.00000-6930898827444486144'
使用decimal.Decimal(1000) / decimal.Decimal(10)
得到的结果也是一样的,所以这并不是因为用整数作为除数的问题。
问题的一部分显然是关于精度的:
>>> decimal.Decimal("1000.000") / decimal.Decimal("10.000")
Decimal('0.00000-6930898827444486144')
>>> decimal.Decimal("1000.000") / decimal.Decimal("10")
Decimal('0.000200376420520689664')
但是在decimal.Decimal("1000.000")
中应该有足够的精度来安全地除以10,并得到一个至少在合理范围内的答案。
这个行为在Python的三个主要版本中都没有变化,这让我觉得这不是一个错误。
我到底做错了什么?我漏掉了什么?
我该如何进行小数除法(除了使用Python 2.4)?
2 个回答
0
仅供参考:对于在OS X上通过Homebrew使用clang编译的Python 2.7.3,这个问题似乎已经解决了。
Python 2.7.3 (default, Oct 10 2012, 13:00:00)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> decimal.Decimal(1000) / 10
Decimal('100')
7
根据你在MacPorts上遇到的bug,你安装了Xcode 4,而你的Python 2.7.2是用clang这个C编译器构建的,而不是gcc-4.2。其实在OS X上,用clang构建时有一个已知的问题,这个问题在2.7.2版本之后的Python中已经修复了。你可以选择应用补丁,或者更好的办法是确保构建时使用gcc-4.2。像这样做(未经测试!):
sudo bash
export CC=/usr/bin/gcc-4.2
port clean python27
port upgrade --force python27
在构建之前,可能会有效,如果MacPorts没有覆盖它的话。
更新:现在所需的补丁已经应用到Python 2的MacPorts端口文件中了。详情请见 https://trac.macports.org/changeset/87442