संख्याओं का जादू: 0.1 + 0.2, 0.3 के बराबर क्यों नहीं है?
\n\nनमस्ते, भविष्य के जावास्क्रिप्ट गुरु! यदि आपने कभी ब्राउज़र कंसोल में 0.1 और 0.2 को जोड़ने का प्रयास किया है, तो संभवतः आपको एक सांस्कृतिक झटका लगा होगा:
\n\nconsole.log(0.1 + 0.2); // आउटपुट: 0.30000000000000004\n\nहाँ, जावास्क्रिप्ट पागल नहीं हुआ है। यह फ्लोटिंग पॉइंट अंकगणित (IEEE 754) की एक मानक समस्या है। कंप्यूटर बाइनरी सिस्टम में 0.1 को पूरी तरह से प्रस्तुत नहीं कर सकते - यह दशमलव में 1/3 लिखने की कोशिश करने जैसा है। परिणाम एक अनंत भिन्न होता है।
\n\nऔर यहाँ Stack Overflow पर एक क्लासिक प्रश्न उठता है, जिसे हजारों बार देखा गया है: "How to round to at most 2 decimal places, if necessary"। संख्या को बिना '0000000004' पूंछ के खूबसूरती से कैसे प्रदर्शित करें? केवल आवश्यक होने पर ही दो दशमलव तक कैसे गोल करें?
\n\nइस लेख में हम एक चरण-दर-चरण ट्यूटोरियल देखेंगे जो इस समस्या को हमेशा के लिए हल कर देगा। आप जानेंगे कि toFixed() कभी-कभी झूठ क्यों बोलता है, Math.round() कैसे काम करता है, और ऑनलाइन स्टोर, कैलकुलेटर या केवल मूल्य को खूबसूरती से प्रदर्शित करने के लिए कौन सी विधि चुननी चाहिए।
समस्या: "मुझे 2 अंक चाहिए, लेकिन इससे अधिक नहीं!"
\n\nकल्पना करें कि आप एक शॉपिंग कार्ट लिख रहे हैं। उत्पाद की कीमत 10.00 है। आप 10 दिखाना चाहते हैं, न कि 10.00। लेकिन अगर कीमत 10.456 है, तो आप 10.46 दिखाना चाहते हैं। तर्क सरल है: हम दो दशमलव तक गोल करते हैं, लेकिन अतिरिक्त शून्य हटा देते हैं।
मानक विधि toFixed(2) यह करती है:
const price = 10;\nconsole.log(price.toFixed(2)); // "10.00" — लेकिन हमें "10" चाहिए\n\nconst price2 = 10.456;\nconsole.log(price2.toFixed(2)); // "10.46" — यह ठीक है\n\nसमस्या: toFixed() हमेशा एक स्ट्रिंग लौटाता है और हमेशा शून्य जोड़ता है। यह उपयुक्त नहीं है।
दूसरी बारीकी — toFixed() उसी फ्लोटिंग पॉइंट के कारण अजीब तरीके से गोल कर सकता है:
console.log((1.005).toFixed(2)); // "1.00" — लेकिन "1.01" होना चाहिए!\n\nबिंगो! यही कारण है कि Stack Overflow पर प्रश्न इतना लोकप्रिय है। आइए समाधानों पर नज़र डालें।
\n\nसमाधान #1: गणितीय गोलाई (Math.round)
\n\nसबसे विश्वसनीय तरीका है संख्या को 100 से गुणा करना, गोल करना, फिर वापस विभाजित करना। यह इस प्रकार काम करता है:
\n\nfunction roundToTwo(num) {\n return Math.round(num * 100) / 100;\n}\n\nconsole.log(roundToTwo(10.456)); // 10.46\nconsole.log(roundToTwo(10)); // 10\nconsole.log(roundToTwo(1.005)); // 1 — उफ़, फिर से समस्या\n\nदेखा? 1.005 * 100 = 100.49999999999999 (IEEE 754 के कारण)। Math.round इसे नीचे गोल करता है, परिणाम 100 आता है, 100 से विभाजित करने पर 1 आता है। अच्छा नहीं है।
निष्कर्ष: यह विधि सरल मामलों के लिए अच्छी है, लेकिन वित्तीय गणनाओं के लिए नहीं। शैक्षिक उदाहरणों के लिए — ठीक है।
\n\nसमाधान #2: Number.EPSILON — सटीकता का उद्धारकर्ता
\n\nफ्लोटिंग पॉइंट त्रुटि को दूर करने के लिए, हम एक छोटा सा डेल्टा — Number.EPSILON जोड़ सकते हैं। यह दो संख्याओं के बीच न्यूनतम अंतर है जिसे जावास्क्रिप्ट पहचान सकता है (लगभग 2.2e-16)।
function roundToTwo(num) {\n return Math.round((num + Number.EPSILON) * 100) / 100;\n}\n\nconsole.log(roundToTwo(1.005)); // 1.01 — काम करता है!\nconsole.log(roundToTwo(10.456)); // 10.46\nconsole.log(roundToTwo(10)); // 10\n\nयह क्यों काम करता है? हम संख्या को थोड़ा ऊपर धकेलते हैं, ताकि 100.4999... 100.5... में बदल जाए और सही ढंग से गोल हो जाए।
महत्वपूर्ण: यह विधि सभी सीमांत मामलों के लिए आदर्श नहीं है, लेकिन 99% कार्यों के लिए — एक उत्कृष्ट समाधान है। Stack Overflow पर अक्सर इसी की सिफारिश की जाती है।
\n\nसमाधान #3: toFixed() + Number() — एक चालाक ट्रिक
\n\nएक और लोकप्रिय तरीका है toFixed(2) का उपयोग करना, और फिर स्ट्रिंग को Number() या यूनरी प्लस + के माध्यम से वापस संख्या में बदलना। अतिरिक्त शून्य हटा दिए जाते हैं।