2008-11-29 28 views
9

मेरा कार्यक्रम में मैं 25 डबल मूल्यों 0.04 के साथ एक सरणी है जब मैं एक पाश में इन मूल्यों को योग करने के लिए मैं निम्नलिखित परिणाम प्राप्त करने की कोशिश:अजीब फ्लोटिंग प्वाइंट व्यवहार

0.0 + 0.04 = 0.04 
0.04 + 0.04 = 0.08 
0.08 + 0.04 = 0.12 
0.12 + 0.04 = 0.16 
0.16 + 0.04 = 0.2 
0.2 + 0.04 = 0.24000000000000002 
0.24000000000000002 + 0.04 = 0.28 
0.28 + 0.04 = 0.32 
0.32 + 0.04 = 0.36 
0.36 + 0.04 = 0.39999999999999997 
0.39999999999999997 + 0.04 = 0.43999999999999995 
0.43999999999999995 + 0.04 = 0.4799999999999999 
0.4799999999999999 + 0.04 = 0.5199999999999999 
0.5199999999999999 + 0.04 = 0.5599999999999999 
0.5599999999999999 + 0.04 = 0.6 
0.6 + 0.04 = 0.64 
0.64 + 0.04 = 0.68 
0.68 + 0.04 = 0.7200000000000001 
0.7200000000000001 + 0.04 = 0.7600000000000001 
0.7600000000000001 + 0.04 = 0.8000000000000002 
0.8000000000000002 + 0.04 = 0.8400000000000002 
0.8400000000000002 + 0.04 = 0.8800000000000002 
0.8800000000000002 + 0.04 = 0.9200000000000003 
0.9200000000000003 + 0.04 = 0.9600000000000003 

क्यों पृथ्वी पर क्या ऐसा हो सकता है ?!

+0

कुछ हद तक संबंधित प्रश्न: http://stackoverflow.com/questions/327020/why-are-floating-point-values-so-prolific – CesarB

उत्तर

23

प्रोग्रामिंग भाषाओं में फ़्लोटिंग-पॉइंट मानों के लिए सबसे आम भंडारण - IEEE singles and doubles - अधिकांश दशमलव अंशों के लिए सटीक प्रतिनिधित्व नहीं है।

कारण यह है कि वे दशमलव फ़्लोटिंग-पॉइंट प्रारूप की बजाय बाइनरी फ़्लोटिंग-पॉइंट प्रारूप में मूल्यों को संग्रहीत करते हैं। केवल एकमात्र fractional मानों का प्रतिनिधित्व किया जा सकता है जो वास्तव में दो की नकारात्मक शक्तियों के बराबर हैं।

  • 0,5 (2^-1)
  • 0,125 (2^-3)
  • 0,625 (2^-1 + 2^-3)

आदि

: की तरह नंबर

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

+0

"दशमलव की बजाय" थोडा गलत विचार देता है। यदि यह दशमलव का उपयोग करता है, तो यह आंशिक मानों तक ही सीमित होगा जो कि दस की नकारात्मक शक्तियों के बराबर हैं, जिससे वास्तव में बहुत कुछ हल नहीं होता है। आपके उत्तर को पढ़ने वाले किसी व्यक्ति को यह विचार मिल सकता है कि "समस्या तब खत्म हो जाएगी जब उन्होंने केवल बेस 10" – jalf

+0

@jalf का उपयोग किया था, लेकिन कम से कम एक दशमलव फ़्लोटिंग पॉइंट प्रस्तुति आश्चर्यजनक जेब एकाउंटिंग के लिए कम लोगों को आश्चर्यचकित करेगी। 20 निकल का ढेर जोड़ना और वास्तव में एक हिरन नहीं मिलना बहुत से लोगों के लिए आश्चर्यजनक है। एक दशमलव नोटेशन उस मामले को सही तरीके से प्राप्त करेगा, और उन मज़ेदार मुद्दों के लिए व्यापार करेगा जो ग्रेड स्कूल अंकगणितीय पाठ से परिचित होना चाहिए। – RBerteig

14
+0

अधिकांश प्रोग्रामिंग भाषाओं में फ़्लोटिंग-पॉइंट प्रस्तुति के लिए नया दस्तावेज़ बहुत घना है।सीएस शिक्षा में, मैं कम से कम एक वर्ष के साथ लोगों के बाहर इसकी सिफारिश नहीं करता, अगर तीन नहीं। –

+0

मैं सहमत हूं। दूसरी तरफ, आत्म-सिखाए गए चिकित्सकों और ओवरचियर्स के लिए यह अच्छा है कि यह कहां है, यदि वे संख्यात्मक मुद्दों का सामना कर रहे हैं। –

+3

यह अभी भी कुछ लोगों को पता होना चाहिए, भले ही उनके पढ़ने के लिए बहुत घना हो। ;) – jalf

5

अन्य उत्तर उल्लेख क्यों देखें, लेकिन यह से बचने के लिए कैसे नहीं।

  • स्केलिंग::

    कई समाधान कर रहे हैं, तो आपके सभी नंबरों को 0.01 के गुणकों (उदाहरण के लिए) कर रहे हैं, 100 से सब कुछ गुणा और पूर्णांक गणित का उपयोग (जिसमें वही है)।

  • संख्यात्मक प्रकार: यदि आपकी भाषा में संख्यात्मक प्रकार है (जैसे numeric एसक्यूएल में टाइप करें), तो आप इसका उपयोग कर सकते हैं।
  • मनमानी सटीक तर्क: GMP जैसे बिग्नम लाइब्रेरी का उपयोग करें, जो आपको इन संख्याओं को दो पूर्णांक के अनुपात के रूप में प्रस्तुत करने की अनुमति देता है।
  • दशमलव फ़्लोटिंग पॉइंट: यदि आपके पास IEEE-754r में से एक की तरह दशमलव फ़्लोटिंग पॉइंट है, तो आप इसका उपयोग कर सकते हैं।
+0

राशन के लिए +1 – finnw

1

आप फ्लोट और युगल के विकल्प के रूप में जावा BigDecimal कक्षा को देखना चाहते हैं।

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