2016-08-12 8 views
7

用(N)%1つのリターンはInvalidOperation、DivisionImpossible IはDjangoアプリケーションの小数点オブジェクトを使用して、この奇妙なエラーを発見しています:decimal.Decimal全てのn> = 100

ipdb> decimal.Decimal(10) % 1 
    Decimal('0') 
ipdb> decimal.Decimal(100) % 1 
    *** decimal.InvalidOperation: [<class 'decimal.DivisionImpossible'>] 
ipdb> decimal.Decimal(150) % 1 
    *** decimal.InvalidOperation: [<class 'decimal.DivisionImpossible'>] 
ipdb> decimal.Decimal(79) % 1 
    Decimal('0') 
ipdb> decimal.Decimal(100.1) % 2 
    Decimal('0.10') 
ipdb> decimal.Decimal(1000) % 2 
    *** decimal.InvalidOperation: [<class 'decimal.DivisionImpossible'>] 

さらに不思議、このdoesnのを数字が非常に大きくなるまで「Tはipythonで起こる:10進数(380)%1は私のDjangoのアプリを壊したので、私はこれを発見しました:エラーがipdbに限定されていないことを

In [23]: decimal.Decimal(10**27) % 1 
Out[23]: Decimal('0') 

In [24]: decimal.Decimal(10**28) % 1 
--------------------------------------------------------------------------- 
InvalidOperation       Traceback (most recent call last) 
<ipython-input-24-6ceaef82d283> in <module>() 
----> 1 decimal.Decimal(10**28) % 1 

InvalidOperation: [<class 'decimal.DivisionImpossible'>] 

注意を。

このエラーを説明するdocumentationは言う:

Division impossible

This occurs and signals invalid-operation if the integer result of a divide-integer or remainder operation had too many digits (would be longer than precision). The result is [0,qNaN].

任意のアイデア?

+0

私はPython 3でエラーを再現できません。問題なく動作します。 – Anonymous

+0

Python 2で再現できません。 – dawg

+0

Python3.5で最後のエラーを再現できます。 'Decimal(10 ** 28)%1'は' decimal.InvalidOperation:[] 'を返します。 –

答えて

4

私はそれを理解したと思います。これはまだ、私には少し間違って見えるので

decimal.getcontext().prec = 2 

# catch most cases of large or small quotient 
expdiff = self.adjusted() - other.adjusted() 
if expdiff >= context.prec + 1: 
    # expdiff >= prec+1 => abs(self/other) > 10**prec 
    return context._raise_error(DivisionImpossible) 
if expdiff <= -2: 
    # expdiff <= -2 => abs(self/other) < 0.1 
    ans = self._rescale(ideal_exponent, context.rounding) 
    return ans._fix(context) 

そして、私のDjangoのアプリで

は、PRECの調整があります:

source codeを見て、私はこれが見つかりました:

In [39]: decimal.getcontext().prec + 1 
Out[39]: 3 

In [40]: decimal.Decimal(100).adjusted() - decimal.Decimal(0).adjusted() 
Out[40]: 2 

そしてそれはまだ100のように見えるが何の境界内にあるI tのチェック(つまり、2 < 3)ですが、これが問題の原因であると確信しています。なぜライブラリがこれをするのか誰にでもわかることができれば、私はそれをよりよく理解したいと思うでしょう。

+0

私は再現できます。 – dawg

+1

これはあなたが見ている間違ったソースです。 URLは3.2ソースのように見えます。 3.5ソースは、[libmpdec](http:// www)のラッパーである['_decimal'Cモジュール](https://hg.python.org/cpython/file/3.5/Modules/_decimal) .bytereef.org/mpdecimal /)。 – user2357112

関連する問題