8

मैं वर्ग की जड़ें अनुमानित करने के लिए एक फ़ंक्शन लिखने की कोशिश कर रहा था (मुझे पता है कि गणित मॉड्यूल है ... मैं इसे स्वयं करना चाहता हूं), और मैं अस्थायी बिंदु अंकगणित द्वारा खराब हो रहा था। आप इससे कैसे बच सकते हैं?फ्लोटिंग पॉइंट त्रुटियों से कैसे बचें?

>>> sqrt(4) 
2.0000000000000013 
>>> sqrt(9) 
3.00999999999998 

मुझे लगता है मैं सिर्फ round() इस्तेमाल कर सकते हैं, लेकिन मैं यह वास्तव में सटीक बनाने के लिए सक्षम होना चाहते हैं:

def sqrt(num): 
    root = 0.0 
    while root * root < num: 
     root += 0.01 
    return root 

इस का उपयोग करते हुए इन परिणामों है। मैं 6 या 7 अंकों की गणना करने में सक्षम होना चाहता हूं। अगर मैं गोल कर रहा हूं तो यह संभव नहीं होगा। मैं समझना चाहता हूं कि पाइथन में फ़्लोटिंग पॉइंट गणनाओं को सही तरीके से कैसे संभालना है।

+0

शायद कोशिश के लिए "न्यूटन की विधि" देखो, जो है परिशुद्धता के लिए डिजाइन किया गया है? – Michael0x2a

उत्तर

15

इसका वास्तव में पाइथन से कोई लेना देना नहीं है - आप अपने हार्डवेयर के बाइनरी फ़्लोटिंग-पॉइंट अंकगणित का उपयोग करके किसी भी भाषा में वही व्यवहार देखेंगे। पहले read the docs

पढ़ने के बाद, आप बेहतर समझेंगे कि आप नहीं हैं जो आपके कोड में एक सौवां जोड़ते हैं।

>>> from decimal import Decimal 
>>> Decimal(.01) 
Decimal('0.01000000000000000020816681711721685132943093776702880859375') 

कि स्ट्रिंग द्विआधारी चल ("डबल परिशुद्धता" सी में) की सटीक दशमलव मान से पता चलता सन्निकटन सटीक दशमलव मान 0.01 करने के लिए: यह आप वास्तव में क्या जोड़ रहे है। जो चीज आप वास्तव में जोड़ रहे हैं वह 1/100 से थोड़ा बड़ा है।

फ़्लोटिंग-पॉइंट न्यूमेरिक त्रुटियों को नियंत्रित करना "संख्यात्मक विश्लेषण" नामक फ़ील्ड है, और यह एक बहुत बड़ा और जटिल विषय है। जब तक आप इस तथ्य से चौंक जाते हैं कि फ्लोट दशमलव मानों के अनुमान हैं, decimal मॉड्यूल का उपयोग करें। यह आपके लिए "उथले" समस्याओं की दुनिया ले जाएगा।

from decimal import Decimal as D 

def sqrt(num): 
    root = D(0) 
    while root * root < num: 
     root += D("0.01") 
    return root 

तो: उदाहरण के लिए, अपने कार्य को यह छोटा सा संशोधन दिए गए

>>> sqrt(4) 
Decimal('2.00') 
>>> sqrt(9) 
Decimal('3.00') 

यह वास्तव में अधिक नहीं सही है, लेकिन क्योंकि अब यह बिल्कुल एक के बाद एक जोड़ने है सरल उदाहरण में कम चौंकाने वाली हो सकती -hundredth। प्रपत्र I/2**J के मूल्यों:

एक वैकल्पिक तैरता और कुछ है कि वास्तव में एक द्विआधारी नाव के रूप में प्रदर्शनीय है जोड़ने के लिए रहना है। उदाहरण के लिए, 0.01 जोड़ने के बजाय, 0.125 (1/8) या 0.0625 (1/16) जोड़ें।

फिर कंप्यूटिंग वर्ग जड़ों ;-) [दशमलव] (http://docs.python.org/2/library/decimal.html) मॉड्यूल

+0

रिकॉर्ड के लिए मैंने दस्तावेज़ पढ़े थे और मुझे पहले से ही बाइनरी प्रस्तुतियों को संग्रहीत करने के साथ पूरी फ़्लोटिंग पॉइंट सटीकता चीज़ के बारे में पता था। मैं न्यूटन की विधि भूल गया था। आप यहां मेरे सभी प्रश्न उठा रहे हैं! मेरा भाग्यशाली दिन जब आपने एसओ की खोज की। मुझे आश्चर्य है कि दशमलव मॉड्यूल कैसे काम करता है। क्या स्रोत पढ़ने के अलावा पता लगाने का कोई तरीका है? – Aerovistae

+1

खैर, 'दशमलव' मूल रूप से पायथन में लिखा गया था और दशमलव अंकों (0, 1, 2, ..., 9) की सूचियों पर काम किया था। कागज पर अंकगणित कैसे करते हैं हम बहुत अनुकरण करते हैं! "फ़्लोटिंग पॉइंट" को केवल प्रतिनिधित्व के लिए एक (दशमलव) एक्सपोनेंट जोड़ने की आवश्यकता है, और फिर बहुत सावधान रहना ;-) वर्तमान 'दशमलव' मॉड्यूल सी में कोडित है, और यह बहुत अधिक अस्पष्ट है :-( –

+0

जैसा आपने कहा था, मैंने कोशिश की दशमलव मॉड्यूल का उपयोग करके '4 - 3.2' को हल करने के लिए। एक = दशमलव (4) ख = दशमलव (3.2) लेकिन एक - ख परिणाम दशमलव है ('.7999999999999998223643160600') – Srinesh

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