2016-08-12 8 views
7

मैं एक Django अनुप्रयोग में दशमलव वस्तुओं का उपयोग कर रहा है, और पाया यह अजीब त्रुटि:decimal.Decimal (एन)% 1 रिटर्न InvalidOperation, DivisionImpossible सभी 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'>] 

इससे भी अधिक रहस्यमय तरीके से, यह नहीं करता है 'टी IPython में होती हैं जब तक संख्या बहुत बड़ी मिलती है:

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'>] 

ध्यान दें कि त्रुटि ipdb तक ही सीमित नहीं है: मैं इस खोज की है क्योंकि दशमलव (380) 1% से मेरी Django एप्लिकेशन को तोड़ने गया था।

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

मैं अजगर 3 के साथ अपने त्रुटि पुन: पेश करने में असमर्थ हूँ, मुद्दा – Anonymous

+0

बिना काम करता है मैं अजगर 2 – dawg

+0

में पुन: पेश करने मैं Python3.5 में अपने अंतिम त्रुटि repro सकते में असमर्थ हूँ। 'दशमलव (10 ** 28)% 1' एक दशमलव को फेंक देता है। अविश्वसनीय ऑपरेशन: [<वर्ग 'दशमलव .डिजन असंभव'>]' –

उत्तर

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 जैसा दिखता है, टी की जांच (यानी, 2 < 3) है, लेकिन मुझे पूरा विश्वास है कि यह समस्या का स्रोत है। यदि कोई मेरे लिए रोशनी कर सकता है तो पुस्तकालय ऐसा क्यों करता है, मुझे इसे बेहतर समझना अच्छा लगेगा।

+0

मैं पुन: पेश करने में सक्षम हूं। – dawg

+1

यह गलत स्रोत है जिसे आप देख रहे हैं। यूआरएल ऐसा लगता है कि यह 3.2 स्रोत के लिए है। 3.5 स्रोत सबकुछ ['_decimal' सी मॉड्यूल] (https://hg.python.org/cpython/file/3.5/Modules/_decimal) में प्रस्तुत करता है, जो [libmpdec] के आसपास एक रैपर है (http: // www .bytereef.org/mpdecimal /)। – user2357112

संबंधित मुद्दे