划分小数在Python 2.5到2.7中产生无效结果

Jos*_*der 12 python numbers decimal

在仔细阅读了Python的十进制模块文档之后,我仍然发现自己对分割小数时会发生什么感到困惑.

在Python 2.4.6中(有意义):

>>> import decimal
>>> decimal.Decimal(1000) / 10
Decimal("100")
Run Code Online (Sandbox Code Playgroud)

在Python 2.5.6,Python 2.6.7和Python 2.7.2(令人费解)中:

>>> import decimal
>>> decimal.Decimal(1000) / 10
Decimal('0.00000-6930898827444486144')
Run Code Online (Sandbox Code Playgroud)

更令人困惑的是,这个结果似乎没有效果:

>>> 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'
Run Code Online (Sandbox Code Playgroud)

结果是相同的使用decimal.Decimal(1000) / decimal.Decimal(10),因此使用int作为除数不是问题.

部分问题显然是精确度:

>>> decimal.Decimal("1000.000") / decimal.Decimal("10.000")
Decimal('0.00000-6930898827444486144')
>>> decimal.Decimal("1000.000") / decimal.Decimal("10")
Decimal('0.000200376420520689664')
Run Code Online (Sandbox Code Playgroud)

但是应该有足够的精确度decimal.Decimal("1000.000")来安全地划分10并得到一个至少在正确的球场上的答案.

通过Python的三个主要版本改变这种行为的事实告诉我,它不是一个bug.

我究竟做错了什么?我错过了什么?

如何划分小数(不能使用Python 2.4)?

Ned*_*ily 7

从您的MacPorts错误中,您已经安装了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
Run Code Online (Sandbox Code Playgroud)

如果MacPorts没有覆盖它,那么构建之前可能会有效.

更新:所需的补丁现已应用于Python 2的MacPorts端口文件.请参阅https://trac.macports.org/changeset/87442

  • 作为参考,设置适合我的编译器的方法是`configure.compiler gcc-4.2` - 请参阅https://trac.macports.org/ticket/31444#comment:8. (2认同)