python programming फ्लोट नंबरों के साथ पायथन गोलिंग त्रुटि



python software foundation (2)

कोई भी संख्या जिसे दो की सटीक शक्तियों से नहीं बनाया जा सकता है, बिल्कुल फ़्लोटिंग बिंदु संख्या के रूप में प्रदर्शित नहीं किया जा सकता; यह अनुमानित होना चाहिए कभी-कभी निकटतम अनुमान वास्तविक संख्या से कम होगा।

हर कंप्यूटर वैज्ञानिक को फ़्लोटिंग-पॉइंट अंकगणित के बारे में क्या पता होना चाहिए

इस सवाल का पहले से ही एक उत्तर है:

मुझे नहीं पता कि यह एक स्पष्ट बग है, लेकिन एक सिमुलेशन के पैरामीटर को अलग करने के लिए एक पायथन स्क्रिप्ट चलाने के दौरान, मुझे डेल्टा = 0.2 9 और डेल्टा = 0.58 के साथ परिणामों का पता चला था। जांच में, मैंने पाया कि निम्नलिखित पायथन कोड:

for i_delta in range(0, 101, 1):
  delta = float(i_delta) / 100

  (...)

filename = 'foo' + str(int(delta * 100)) + '.dat'

डेल्टा = 0.28 और 0.2 9 के लिए समान फ़ाइलों को उत्पन्न किया गया, इसी प्रकार से .57 और .58, इसका कारण यह है कि अजगर फ्लोट (29) / 100 के रूप में 0.28999999999999998। लेकिन यह एक व्यवस्थित त्रुटि नहीं है, अर्थ में यह हर पूर्णांक के लिए होता है इसलिए मैंने निम्नलिखित पायथन स्क्रिप्ट बनाई है:

import sys

n = int(sys.argv[1])

for i in range(0, n + 1):
  a = int(100 * (float(i) / 100))
  if i != a: print i, a

और मैं उन संख्याओं में कोई भी पैटर्न नहीं देख सकता, जिसके लिए यह गोल त्रुटि हो जाती है। यह उन विशेष संख्याओं के साथ क्यों होता है?


Answer #1

फ्लोटिंग प्वाइंट नंबर की प्रकृति के कारण इसकी बहुत अच्छी तरह से जाना जाता है

यदि आप दशमलव अंकगणित नहीं करना चाहते हैं, तो फ्लोटिंग प्वाइंट अरिथमेटिक नहीं है, ऐसा करने के लिए पुस्तकालय हैं।

उदाहरण के लिए,

>>> from decimal import Decimal
>>> Decimal(29)/Decimal(100)
Decimal('0.29')
>>> Decimal('0.29')*100
Decimal('29')
>>> int(Decimal('29'))
29

सामान्य दशमलव में संभवतया ओव्हरबोर्ड चल रहा है और फिर भी दुर्लभ मामलों में गोलाकार त्रुटियां होंगी जब संख्या में कोई सममित दशमलव प्रस्तुति नहीं होगी (उदाहरण के लिए कोई भी अंश जहां हररा 1 या 2 या 5 से विभाजित नहीं है - दशमलव आधार के कारक (10))। उदाहरण के लिए:

>>> s = Decimal(7)
>>> Decimal(1)/s/s/s/s/s/s/s*s*s*s*s*s*s*s
Decimal('0.9999999999999999999999999996')
>>> int(Decimal('0.9999999999999999999999999996'))
0

तो सबसे अच्छा करने के लिए हमेशा ints को फ्लोटिंग अंक कास्टिंग से पहले हमेशा गोल, जब तक आप एक मंजिल समारोह चाहते हैं

>>> int(1.9999)
1
>>> int(round(1.999))
2

एक और विकल्प अंश पुस्तकालय से अंतर वर्ग का उपयोग करना है जो अनुमानित नहीं है। (यह जरूरी है कि पूर्णांक संख्याओं और निगोशिएटरों को जोड़ना / घटाना और गुणा करना)।





python