2010-10-29 16 views
9

क्या कोई बता सकता है कि 100 से गुणा क्यों कम सटीक परिणाम देता है लेकिन 10 बार गुणा करके अधिक सटीक परिणाम मिलता है?रूबी फ्लोटिंग पॉइंट त्रुटियां

± % sc 
Loading development environment (Rails 3.0.1) 
>> 129.95 * 100 
12994.999999999998 
>> 129.95*10 
1299.5 
>> 129.95*10*10 
12995.0 
+1

सबसे अधिक संभावना चल बिन्दु संख्या के द्विआधारी प्रतिनिधित्व के कारण। मुझे लगता है कि बेस 2 में आप 12 9.9 5 बिल्कुल नहीं लिख सकते हैं। –

+10

अनिवार्य लिंक: [प्रत्येक कंप्यूटर वैज्ञानिक को फ्लोटिंग-प्वाइंट अंकगणितीय के बारे में क्या पता होना चाहिए] (http://docs.sun.com/source/806-3568/ncg_goldberg.html) –

+0

इस पर कोई संकेत नहीं है कि यह क्यों नहीं होगा मुझे? मैं इसे प्रदर्शित करने की कोशिश कर रहा हूं, और मैं ऊपर आईआरबी में 12 9.9 5 * 100 दर्ज करता हूं और मुझे अप्रत्याशित रूप से सही उत्तर मिलता है। – Joel

उत्तर

22

आप डबल परिशुद्धता बाइनरी, जो 53 महत्वपूर्ण बिट तक ही सीमित है में हाथ से गणना करते हैं, तो आप देखेंगे क्या हो रहा है:

129,95 = 1,0000001111100110011001100110011001100110011001100110 एक्स 2^7

129,95 * 100 = 1.1001011000010111111111111111111111111111111111111111011 एक्स 2^13

यह 56 महत्वपूर्ण बिट लंबे, इसलिए 53 बिट के लिए गोल यह

1,10010110000101111111111111111111111111111111111111 है 11 x 2^13 है, जो बराबर होती है

12994,999999999998181010596454143524169921875

अब 129.95 * 10 = 1.01000100110111111111111111111111111111111111111111111 एक्स 2^10

यह 54 महत्वपूर्ण बिट लंबे, इसलिए 53 बिट यह है करने के लिए गोल है १.०१०००१००१११ एक्स 2^10 = 1299,5

अब 1299.5 * 10 = 1.1001011000011 एक्स 2^13 = 12995.

3

सबसे पहले: आप परिणाम की स्ट्रिंग प्रस्तुति को देख रहे हैं, न कि वास्तविक परिणाम। यदि आप वास्तव में दो परिणामों की तुलना करना चाहते हैं, तो आपको String#% का उपयोग करके दोनों परिणामों को स्पष्ट रूप से प्रारूपित करना चाहिए और आपको दोनों परिणामों को उसी तरह प्रारूपित करना चाहिए।

दूसरा, यह है कि बाइनरी फ़्लोटिंग पॉइंट नंबर कैसे काम करते हैं। वे अचूक हैं, वे सीमित हैं और वे बाइनरी हैं। इन तीनों का मतलब है कि आपको गोल करने वाली त्रुटियां मिलती हैं, जो आमतौर पर पूरी तरह से यादृच्छिक लगती हैं, जब तक कि आप IEEE754 की संपूर्णता को याद नहीं करते हैं और इसे अपनी नींद में पीछे की ओर पढ़ सकते हैं।

2

129.95 के बराबर कोई फ़्लोटिंग पॉइंट नंबर नहीं है। तो आपकी भाषा उस मान का उपयोग करती है जो इसके करीब है। जब वह मान 100 से गुणा हो जाता है, तो परिणाम 12 99 5 के करीब होता है, लेकिन यह 12995 के बराबर नहीं होता है। (यह 129.95 के स्थान पर मूल मूल्य के बराबर 100 गुणा के बराबर नहीं है।) तो आपके दुभाषिया प्रिंट एक दशमलव संख्या जो 129.95 * 100 के मान (लेकिन बराबर नहीं) के करीब है और जो आपको दिखाती है कि यह बिल्कुल 12995 नहीं है। यह भी ऐसा होता है कि परिणाम 129.95 * 10 बिल्कुल 1299.5 के बराबर है। यह ज्यादातर भाग्य है।

नीचे की रेखा किसी भी फ़्लोटिंग पॉइंट अंकगणित, केवल "निकटता" से समानता की अपेक्षा नहीं करती है।

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