2016-02-15 10 views
5

यह वास्तव में एक समस्या नहीं है, यह पाइथन कार्यान्वयन पर फ़्लोटिंग-पॉइंट अंकगणित के बारे में कुछ उत्सुक है।शून्य के पास विभाजन के पास अजगर में अलग-अलग व्यवहार क्यों हैं?

क्या कोई निम्नलिखित व्यवहार को समझा सकता है?

>>> 1/1e-308 
1e+308 
>>> 1/1e-309 
inf 
>>> 1/1e-323 
inf 
>>> 1/1e-324 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ZeroDivisionError: float division by zero 

ऐसा लगता है कि 1 शून्य करने के लिए के निकट एक संख्या से विभाजित inf है और अगर यह एक ZeroDivisionError के निकट है फेंक दिया है। यह एक अजीब व्यवहार लगता है।

पायथन 2.x/3.x के लिए एक ही आउटपुट।


संपादित: यहाँ मेरा मुख्य सवाल यह है कि क्यों हम कुछ श्रृंखला के लिए inf हो और कि अजगर संभालने नहीं ZeroDivisionError विचार करने के लिए के रूप में शून्य 1e-309

उत्तर

7

यह IEEE754 फ्लोटिंग प्वाइंट से संबंधित है लगता है अपने आप को प्रारूपित करें, इतना पाइथन इसका कार्यान्वयन नहीं है।

आम तौर पर बोलते हुए, denormal numbers की वजह से फ्लोट बड़े सकारात्मक लोगों की तुलना में छोटे नकारात्मक घाटे का प्रतिनिधित्व कर सकते हैं। यही वह जगह है जहां फ्लोट का मंथिसा हिस्सा अब 1 से शुरू होने वाला नहीं माना जाता है, बल्कि पूरे मंटिसा का वर्णन करता है, और शून्य से शुरू होता है। यदि आपको पता नहीं है कि यह क्या है, तो मैं आपको सुझाव दूंगा कि फ्लोट का प्रतिनिधित्व कैसे किया जाता है, शायद here से शुरू हो रहा है।

इस वजह से, जब आप एक असामान्य संख्या को घुमाते हैं, तो आप प्रतिनिधित्व करने के लिए एक सकारात्मक एक्सपोनेंट के साथ समाप्त हो सकते हैं। कंप्यूटर आपको इसके स्थान पर inf देता है। आपके उदाहरण में 1e-308 वास्तव में भी असामान्य है, लेकिन उलटा होने पर अभी भी अतिप्रवाह नहीं है (क्योंकि सामान्य संख्याओं के बीच, मानक वास्तव में नकारात्मक घाटे से थोड़ा बड़ा सकारात्मक अनुमति देता है)।

1e-324 के मामले में, यह संख्या केवल एक छोटे से के रूप में प्रतिनिधित्व करने के लिए बहुत छोटा है, ताकि फ्लोटल शून्य प्रभावी रूप से शून्य के बराबर हो। यही कारण है कि आप शून्य से विभाजन प्राप्त करते हैं। सबसे छोटा प्रतिनिधित्व करने वाला 64-बिट फ्लोट (थोड़ा नीचे) 5e-324 है।

+1

यह आईईईई 754 के पायथन (गैर-) कार्यान्वयन से पूरी तरह से संबंधित है। एक सेन प्रोग्रामिंग भाषा विभाजन को होने देगी (प्रोसेसर इसे पाइथन डिजाइनरों के विपरीत सही ढंग से लागू करता है) और उपयुक्त परिणाम उत्पन्न करता है। इसके बजाए, पायथन स्पष्ट रूप से जांच करता है कि क्या विभाजक शून्य है और इस मामले में अलग-अलग व्यवहार करता है। यह अतिरिक्त चक्र लेता है, ओवरफ्लो होने से नहीं रोकता है, और इसका मतलब है कि पायथन आईईईई 754 अनुरूप नहीं है (क्योंकि आईईईई 754 1.0/0.0 उत्पादन + inf) में है। –

+1

@ पास्कल क्यूओक: तकनीकी रूप से, यह पूरी तरह से सच नहीं है, क्योंकि आपको आईईईई 754 अंकगणितीय * के साथ अपवाद मिलेगा यदि आपके पास जाल सक्षम है *। चूंकि यह डिफ़ॉल्ट व्यवहार से बहुत दूर है, हालांकि, आपका बिंदु मान्य, स्वीकार और उल्लेखनीय है। हालांकि, दो व्यवहारों के बीच का अंतर ओवरफ्लो को उत्पादित करने की अनुमति देने वाले denormals के उलटा द्वारा समझाया गया है, इसलिए मुझे नहीं लगता कि उत्तर को सुधारने की जरूरत है। – Dolda2000

4

न्यूनतम मूल्य है कि अजगर में नाव numer के रूप में इस्तेमाल किया जा सकता है:

2.2250738585072014e-308

अजगर डबल परिशुद्धता तैरता है, जो 308 सत्ता में 10 के बारे में 10 -308 से मान हो सकते हैं का उपयोग करता है ।

Wikipedia - double precision floating point format

वास्तव में, आप शायद संख्या 1e-308 denormals के माध्यम से की तुलना में छोटे हो सकता है, लेकिन इस के लिए एक महत्वपूर्ण प्रदर्शन हिट है। मैंने पाया कि पायथन 1e-324 को संभालने में सक्षम है लेकिन 1e-325 पर बहती है और मूल्य के रूप में 0.0 लौटाती है।

+0

धन्यवाद, मैं देखता हूं। हालांकि, मुझे अभी तक समझ में नहीं आ रहा है कि हमें थोड़ी सी सीमा के लिए 'inf' क्यों मिलता है और' ज़ीरो डिविजन एरर 'नहीं है क्योंकि पाइथन वापस आना चाहिए। क्या यह भाषा डिजाइन में कुछ जानबूझकर हो सकता है? –

+0

@emartinelli जैसा कि मैंने परीक्षण किया था '1e-323' शून्य के बराबर नहीं है लेकिन पायथन शेल में '1e-324' शून्य के बराबर है, इसलिए विभाजन ByZero क्यों उठाया गया। और जैसा कि मैंने पायथन में न्यूनतम मान का उल्लेख किया है, फ्लोट के रूप में '2.22e-308' है और इस मान से छोटा है, मुझे लगता है कि पाइथन उनके साथ कोई गणितीय गणना नहीं करता है और 'divideByZero' त्रुटि – Arman

+1

" नहीं बढ़ाता है, * लेकिन इस पर एक महत्वपूर्ण प्रदर्शन मारा गया है "- बस रिकॉर्ड के लिए, यह जरूरी नहीं है। मेरा मानना ​​है कि इंटेल और एएमडी हैंडल के अधिकांश बड़े आर्किटेक्चर, बिना किसी अतिरिक्त जुर्माना के इंफिनिटीज और एनएनएस हैंडल हैं। साथ ही, यह भी कहा जाना चाहिए कि किसी भी तरह से चल रहे पाइथन कोड के दंड की तुलना में जुर्माना बल्कि छोटा हो जाएगा। ;) – Dolda2000

2

अधिकांश चीजों को पहले से ही answer में डोल्डा 2000 द्वारा समझाया गया है। फिर भी यह के लिए उपयोगी हो सकता है यह देखें।

>>> 1e-308 
1e-308 
>>> 1e-309 
1e-309 
>>> 1e-323 
1e-323 
>>> 1e-324 
0.0 

आप 1e-324 देख सकते हैं अजगर कार्यान्वयन में 0.0 के बराबर है।चूंकि डोल्डा 2000 ने इसे बहुत अच्छी तरह से रखा है: यह संख्या केवल असामान्य रूप से प्रदर्शित होने के लिए बहुत छोटी है, ताकि फ्लोटल प्रभावी रूप से शून्य

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