0.1 + 0.2 का जवाब 0.30000000000000004 क्यों आता है

बाइनरी फ्लोटिंग पॉइंट में 0.1 और 0.2 जोड़ने पर 0.30000000000000004 क्यों मिलता है, और यह कैलकुलेटर इसे राउंड करके साफ-सुथरा 0.3 कैसे दिखाता है।

बाइनरी फ्लोटिंग पॉइंट पर चलने वाले लगभग किसी भी कैलकुलेटर में 0.1 + 0.2 टाइप करें, तो कच्चा जवाब 0.30000000000000004 आता है, 0.3 नहीं। यह कैलकुलेटर भी अंदर से वही वैल्यू निकालता है, फिर उसे डिस्प्ले के लिए राउंड कर देता है, इसलिए आपको 0.3 दिखता है। असली वजह है बेस का मेल न खाना: इंसान संख्याएँ बेस 10 में लिखते हैं, कंप्यूटर उन्हें बेस 2 में स्टोर करता है, और 0.1 बेस 2 में बिल्कुल सटीक रूप से मौजूद ही नहीं है।

मुख्य बातें

  • 0.1 + 0.2 हर भाषा में बाइनरी फ्लोटिंग पॉइंट में 0.30000000000000004 ही आता है।
  • बाइनरी में 0.1 एक दोहराया जाने वाला पैटर्न है, 0.0001100110011…।
  • यह कैलकुलेटर नतीजों को 12 सिग्निफिकेंट अंकों तक राउंड करता है, इसलिए यह असली डबल नहीं बल्कि 0.3 दिखाता है।
  • 0.1 की स्टोर की गई वैल्यू असल में 0.10000000000000000555111512312578… निकलती है।

ये अतिरिक्त अंक कहाँ से आते हैं

आप पहले से जानते हैं कि कुछ भिन्न बेस 10 में साफ-साफ फिट नहीं होतीं। एक तिहाई 0.333… है, जो हमेशा के लिए दोहराता रहता है, क्योंकि 3, 10 का गुणनखंड नहीं है। कंप्यूटर संख्याएँ बेस 2 में स्टोर करते हैं, जहाँ केवल वही भिन्नें साफ-सुथरी बनती हैं जिनके हर में 2 की घात हो: आधा, चौथाई, आठवाँ भाग। एक दहाई (0.1) उस सूची में नहीं है। बाइनरी में 0.1, 0.0001100110011… है, जो हमेशा दोहराता है, ठीक उसी तरह जैसे दशमलव में एक तिहाई दोहराता है।

डबल-प्रिसिज़न संख्या में अंकों के लिए 53 बिट होते हैं, इसलिए यह अनंत बाइनरी विस्तार बीच में ही काट दिया जाता है। जब आप 0.1 टाइप करते हैं तो जो वैल्यू स्टोर होती है वह है 0.1000000000000000055511151231257827021181583404541015625। यह 0.1 के करीब तो है, लेकिन उसके बराबर नहीं। इन दोनों थोड़ी-सी गलत वैल्यू को जोड़ने पर गलतियाँ कटती नहीं हैं; वे जुड़ती जाती हैं, और योग 0.3 से एक कदम आगे जाकर गिरता है। इसी वजह से 0.30000000000000004 मिलता है। यह IEEE 754 स्टैंडर्ड है, जिसे लगभग हर प्रोसेसर और भाषा लागू करती है, इसलिए यही जवाब JavaScript, Python, C और Excel में भी दिखता है।

यह कैलकुलेटर इस बारे में क्या करता है

इस साइट का नियम फ्लोटिंग पॉइंट अंकगणित गाइड में साफ लिखा है: दिखाए जाने से पहले हर नतीजे को 12 सिग्निफिकेंट अंकों तक राउंड किया जाता है। एक डबल में लगभग 15 से 17 भरोसेमंद अंक होते हैं, इसलिए 12 पर राउंड करने से वे सभी अंक बच जाते हैं जिन पर भरोसा किया जा सकता है, और आखिरी कुछ अंक हट जाते हैं, जो ठीक वहीं होते हैं जहाँ जमा हुई गड़बड़ी छिपी होती है।

उदाहरण 1: खुद टाइप करके देखें। मुख्य कैलकुलेटर पर 0.1+0.2 टाइप करें। डिस्प्ले 0.3 लौटाता है। अंदर की असली डबल वैल्यू 0.30000000000000004 है, लेकिन डिस्प्ले का नियम उसे छिपा देता है। यही चाल दूसरी दिशा में भी आज़माएँ, 0.3-0.2 से: कच्चा नतीजा 0.09999999999999998 है, और डिस्प्ले 0.1 दिखाता है। गुणा में भी यही होता है: 1.1*3 अंदर से 3.3000000000000003 रखता है और 3.3 दिखाता है।

जब जवाब वाकई पूरी तरह सटीक तय नहीं किया जा सकता, तो कैलकुलेटर बहानेबाज़ी नहीं करता। 1/3 टाइप करें, यह 0.333333333333 दिखाता है, बारह तीन और फिर रुक जाता है। सिग्निफिकेंट फिगर्स गाइड में यह समझाया गया है कि यह राउंडिंग और ये डिस्प्ले की सीमाएँ ठीक-ठीक कैसे काम करती हैं।

यह फर्क कब मायने रखता है

रोज़मर्रा के हिसाब-किताब, होमवर्क और इंजीनियरिंग अनुमानों के लिए, 12 भरोसेमंद अंक किसी भी माप की ज़रूरत से कहीं ज़्यादा सटीकता हैं। यह तीन खास स्थितियों में मायने रखता है, इन सभी को फ्लोटिंग पॉइंट अंकगणित गाइड में बताया गया है:

  • पैसा। मुद्रा को फ्लोटिंग-पॉइंट संख्या के रूप में स्टोर न करें। पैसे और सेंट को पूर्णांक के रूप में रखना सुरक्षित रास्ता है, और छोटी-छोटी गलतियों के जमा होते चले जाना अकाउंटिंग की जानी-पहचानी गड़बड़ी है।
  • कोड में इक्वैलिटी जाँच। दो कैलकुलेट किए गए फ्लोट बराबर हैं या नहीं, यह टेस्ट करना भरोसेमंद नहीं है; इसकी बजाय एक छोटी सी टॉलरेंस के साथ तुलना करें।
  • ऑपरेशनों की लंबी शृंखला। गलतियाँ जमा होती जाती हैं, और लगभग बराबर दो संख्याओं को घटाने से सबसे ज़्यादा सटीकता खो जाती है।

उदाहरण 2: सटीक भिन्नें। जब आपको बिल्कुल सही भिन्न चाहिए हो, तो फ्रैक्शन कैलकुलेटर अंश और हर को पूर्णांकों के रूप में रखता है और कभी राउंड नहीं करता। वहाँ 1/3 + 1/3 + 1/3 टाइप करें और यह ठीक 1 लौटाता है। यही जोड़ दिखाए गए दशमलवों से करें, 0.333333333333 + 0.333333333333 + 0.333333333333, तो नतीजा 0.999999999999 आता है। सोच एक ही, दुनिया अलग-अलग।

उदाहरण 3: मूल और वर्ग। sqrt(2)^2 एक क्लासिक जाल है। तर्क के हिसाब से, 2 के वर्गमूल का वर्ग 2 होना चाहिए। कैलकुलेटर पर कच्चा नतीजा 2.0000000000000004 है, जिसे डिस्प्ले के लिए 2 तक राउंड किया जाता है। जब आपको सटीक वैल्यू चाहिए, तो मूल के रूप को बनाए रखें और अंत में एक ही बार गणना करें, जिसकी चर्चा कैलकुलेटर फंक्शन रेफरेंस √ कुंजी के अंतर्गत करता है।

एक पूर्णांक सीमा भी जानने लायक है। 2^53 − 1 = 9,007,199,254,740,991 से नीचे, हर पूर्णांक ठीक-ठीक दर्शाया जा सकता है और कैलकुलेटर उसके सारे अंक दिखाता है। इस सीमा से ऊपर, 19! जैसी वैल्यू साइंटिफिक नोटेशन में बदल जाती हैं, बजाय इसके कि वह ऐसी सटीकता का दावा करें जो वास्तव में मौजूद ही नहीं है।

अक्सर पूछे जाने वाले सवाल

क्या 0.1 और 0.2 का जोड़ सच में 0.3 है या नहीं?

सटीक दशमलव अंकगणित में हाँ, यह 0.3 ही है। बाइनरी फ्लोटिंग पॉइंट में, स्टोर किया गया नतीजा 0.30000000000000004 होता है। यह कैलकुलेटर अंदर से वही वैल्यू लौटाता है और डिस्प्ले के लिए 12 सिग्निफिकेंट अंकों तक राउंड करता है, इसलिए आपको 0.3 दिखता है।

क्या यह कैलकुलेटर की कोई गड़बड़ी है?

नहीं। यह IEEE 754 स्टैंडर्ड है, जिसे लगभग हर मुख्यधारा का प्रोसेसर और भाषा लागू करती है। जो प्रोग्राम और कैलकुलेटर इस समस्या से बचते हुए दिखते हैं, वे भी इसे डिस्प्ले राउंडिंग से छिपा रहे होते हैं, ठीक वैसे ही जैसे यह करता है।

सटीक जवाब कैसे पाएँ?

तर्कसंगत अंकगणित के लिए फ्रैक्शन कैलकुलेटर का इस्तेमाल करें, जो कभी राउंड नहीं करता, या अंतिम चरण तक sqrt(2) और pi जैसे सिंबॉलिक रूप बनाए रखें।

1 को 3 से भाग देने पर सिर्फ बारह तीन क्यों दिखते हैं?

क्योंकि एक तिहाई का कोई भी बेस में सटीक निरूपण नहीं है। कैलकुलेटर बारह भरोसेमंद अंक दिखाता है और रुक जाता है, बजाय इसके कि यह दिखावा करे कि यह वैल्यू कहीं खत्म होती है।