वित्त की तेज़ गति वाली दुनिया में, सटीकता ही सब कुछ है। राउंडिंग/परिशुद्धता त्रुटि के कारण लाखों डॉलर के नुकसान से बचना हमेशा बेहतर होता है।
इस लेख का शुरुआती बिंदु यह अहसास है कि पैसा आपकी औसत मूल संख्या नहीं है जिसका उपयोग आप अपनी टोकरी में सेब गिनने के लिए कर सकते हैं। जब आप 10€ को 10$ से गुणा करने का प्रयास करते हैं तो आपको क्या मिलता है? कठिन हुह... क्या आपको कभी किसी पुराने जैकेट की जेब में चमत्कारी $1.546 मिला है? हाँ, मैं जानता हूँ, यह वास्तव में संभव भी नहीं है। ये मूर्खतापूर्ण उदाहरण इस तथ्य को स्पष्ट करने के लिए यहां हैं कि पैसे के अपने विशेष नियम हैं और इसे केवल एक साधारण संख्या के आधार पर नहीं बनाया जा सकता है। मैं आपको आश्वस्त करता हूं, मैं पहला व्यक्ति नहीं हूं जिसे इसका एहसास हुआ (और हो सकता है कि आपको मुझसे पहले ही इसका एहसास हो गया हो)। 2002 में, प्रोग्रामर मार्टिन फाउलर ने एंटरप्राइज एप्लिकेशन आर्किटेक्चर के पैटर्न में विशिष्ट विशेषताओं और ऑपरेंड नियमों के साथ पैसे का प्रतिनिधित्व करने का एक तरीका प्रस्तावित किया। उनके लिए, धन डेटाटाइप के लिए आवश्यक दो न्यूनतम व्यवहार्य विशेषताएँ थीं:
amount currency
यह वास्तव में बुनियादी प्रतिनिधित्व एक सरल लेकिन मजबूत मौद्रिक मॉडल के निर्माण के लिए हमारा शुरुआती बिंदु होगा।
एक धन राशि निश्चित रूप से एक विशेष संख्या है: इसकी एक निश्चित सटीकता होती है (फिर से, आपकी जेब में 4.376$ नहीं हो सकते)। आपको इसका प्रतिनिधित्व करने का एक तरीका चुनना होगा जो आपको इस बाधा का सम्मान करने में मदद करे।
स्पॉयलर अलर्ट, यह निश्चित रूप से एक अच्छा विचार नहीं है यदि आप फ्लोटिंग-पॉइंट संख्या प्रतिनिधित्व की अंधेरी दुनिया में कुछ सेंट (यदि यह डॉलर नहीं है) को गायब होते नहीं देखना चाहते हैं।
यदि आपके पास जावास्क्रिप्ट में कोडिंग का कुछ अनुभव है, तो आप जानते हैं कि सबसे सरल गणना के परिणामस्वरूप भी सटीक त्रुटि हो सकती है जिसकी आपको पहले उम्मीद नहीं होगी। इस घटना को उजागर करने वाला सबसे स्पष्ट और प्रसिद्ध उदाहरण है:
0.1 0.2 !== 0.3 // true 0.1 0.2 // 0.30000000000000004
यदि यह उदाहरण आपको पूरी तरह से आश्वस्त नहीं करता है, तो मैं आपको सलाह देता हूं कि आप इस लेख पर एक नजर डालें, जो उन सभी समस्याग्रस्त गणना परिणामों के बारे में थोड़ा और विस्तार से बताता है जिनका सामना आप जावास्क्रिप्ट मूल संख्या प्रकार के साथ काम करते समय कर सकते हैं...
परिणामों में यह मामूली डेल्टा आपके लिए हानिरहित प्रतीत हो सकता है (लगभग ~ 10^-16 की परिमाण के साथ), हालांकि एक महत्वपूर्ण वित्तीय अनुप्रयोग में, ऐसी त्रुटि तेजी से बढ़ सकती है। हजारों खातों के बीच धनराशि स्थानांतरित करने पर विचार करें, जहां प्रत्येक लेनदेन में समान गणना शामिल होती है। थोड़ी-सी अशुद्धियाँ बढ़ती जाती हैं, और इससे पहले कि आपको इसका पता चले, आपके वित्तीय विवरणों में हजारों डॉलर का नुकसान हो जाता है। और ईमानदारी से, हम सभी इस बात से सहमत हो सकते हैं कि जब पैसे की बात आती है, तो गलती की अनुमति नहीं है: कानूनी रूप से भी और अपने ग्राहकों के साथ भरोसेमंद संबंध बनाने के लिए भी।
अपने किसी प्रोजेक्ट में समस्या का सामना करते समय मैंने खुद से जो पहला सवाल पूछा वह है क्यों ? मैंने पाया कि समस्या का स्रोत जावास्क्रिप्ट नहीं है और ये अशुद्धियाँ अन्य आधुनिक प्रोग्रामिंग भाषाओं (जावा, सी, पायथन…) को भी प्रभावित करती हैं।
// In C #includeint main() { double a = 0.1; double b = 0.2; double sum = a b; if (sum == 0.3) { printf("Equal\n"); } else { printf("Not Equal\n"); // This block is executed } return 0; } // > Not equal
// In Java public class doublePrecision { public static void main(String[] args) { double total = 0; total = 5.6; total = 5.8; System.out.println(total); } } // > 11.399999999999
वास्तव में, मूल कारण इन भाषाओं द्वारा फ़्लोटिंग-पॉइंट संख्याओं का प्रतिनिधित्व करने के लिए उपयोग किए जाने वाले मानक में निहित है: आईईईई 754 मानक द्वारा निर्दिष्ट डबल (या एकल)-सटीक फ़्लोटिंग-पॉइंट प्रारूप।
जावास्क्रिप्ट में, मूल प्रकार की संख्या डबल-सटीक फ़्लोटिंग-पॉइंट संख्याओं से मेल खाती है, जिसका अर्थ है कि एक संख्या 64 बिट्स के साथ एन्कोड की गई है और तीन भागों में विभाजित है:
फिर, आपको अपने बिट प्रतिनिधित्व को दशमलव मान में बदलने के लिए निम्नलिखित सूत्र का उपयोग करने की आवश्यकता है:
डबल-प्रिसिजन फ़्लोटिंग-पॉइंट संख्या प्रतिनिधित्व का एक उदाहरण, 1/3 का अनुमान:
0 01111111101 0101010101010101010101010101010101010101010101010101 = (-1)^0 x (1 2^-2 2^-4 2^-6 ... 2^-50 2^-52) x 2^(1021-1023) = 0.333333333333333314829616256247390992939472198486328125 ~ 1/3
यह प्रारूप हमें मूल्यों की एक विस्तृत श्रृंखला का प्रतिनिधित्व करने की अनुमति देता है, लेकिन यह पूर्ण सटीकता के साथ हर संभव संख्या का प्रतिनिधित्व नहीं कर सकता है (केवल 0 और 1 के बीच आप संख्याओं की अनंत संख्या पा सकते हैं...)। कई संख्याओं को बाइनरी रूप में सटीक रूप से प्रदर्शित नहीं किया जा सकता है। पहले उदाहरण पर लूप करने के लिए, 0.1 और 0.2 के साथ यही समस्या है। डबल-पॉइंट फ़्लोटिंग प्रतिनिधित्व हमें इन मानों का अनुमान देता है, इसलिए जब आप इन दो अस्पष्ट प्रतिनिधित्वों को जोड़ते हैं, तो परिणाम भी सटीक नहीं होता है।
अब जब आप पूरी तरह से आश्वस्त हो गए हैं कि मूल जावास्क्रिप्ट नंबर प्रकार के साथ धन राशि को संभालना एक बुरा विचार है (कम से कम मुझे आशा है कि आपको इसके बारे में संदेह होना शुरू हो जाएगा), 1 अरब डॉलर का सवाल यह है कि आपको कैसे आगे बढ़ना चाहिए ? इसका समाधान जावास्क्रिप्ट में उपलब्ध कुछ शक्तिशाली निश्चित-सटीक अंकगणितीय पैकेजों का उपयोग करना हो सकता है। उदाहरण के लिए Decimal.js (जिसका उपयोग लोकप्रिय ORM प्रिज्मा द्वारा अपने दशमलव डेटाटाइप को दर्शाने के लिए किया जाता है) या Big.js.
ये पैकेज आपको विशेष डेटाटाइप प्रदान करते हैं जो आपको ऊपर बताई गई सटीक त्रुटियों से छुटकारा पाने के साथ गणना करने की अनुमति देते हैं।
// Example using Decimal.js const Decimal = require('decimal.js'); const a = new Decimal('0.1'); const b = new Decimal('0.2'); const result = a.plus(b); console.log(result.toString()); // Output: '0.3'
यह दृष्टिकोण आपको एक और लाभ प्रदान करता है, यह प्रतिनिधित्व किए जा सकने वाले अधिकतम मूल्य को काफी हद तक बढ़ाता है, जो उदाहरण के लिए क्रिप्टोकरेंसी के साथ काम करते समय काफी उपयोगी हो सकता है।
भले ही यह वास्तव में मजबूत हो, लेकिन यह वह नहीं है जिसे मैं अपने वेब अनुप्रयोगों में लागू करना पसंद करता हूं। मुझे केवल पूर्णांक मानों से निपटने के लिए Stripe रणनीति लागू करना आसान और स्पष्ट लगता है।
हम, थियोडो फिनटेक में, व्यावहारिकता को महत्व देते हैं! हम उद्योग की सबसे सफल कंपनियों से प्रेरणा लेना पसंद करते हैं। भुगतान सेवाओं में विशेषज्ञता वाली प्रसिद्ध अरबों डॉलर की कंपनी स्ट्राइप ने फ्लोटिंग नंबरों के बिना बल्कि पूर्णांक के साथ धन राशि को संभालने का विकल्प चुना। ऐसा करने के लिए, वे मौद्रिक राशि का प्रतिनिधित्व करने के लिए मुद्रा की सबसे छोटी इकाई का उपयोग करते हैं।
// 10 USD are represented by { "amount": 1000, "currency": "USD" }
मुझे लगता है कि आप में से कई लोग यह पहले से ही जानते हैं: सभी मुद्राओं में समान परिमाण की सबसे छोटी इकाई नहीं होती है। उनमें से अधिकांश "दो-दशमलव" मुद्राएं (EUR, USD, GBP) हैं जिसका अर्थ है कि उनकी सबसे छोटी इकाई मुद्रा का 1/100वां हिस्सा है। हालाँकि, कुछ "तीन-दशमलव" मुद्राएँ (KWD) या यहाँ तक कि "शून्य-दशमलव" मुद्राएँ (JPY) भी हैं। (आप ISO4217 मानक का पालन करके इसके बारे में अधिक जानकारी प्राप्त कर सकते हैं)। इन असमानताओं को संभालने के लिए, आपको सबसे छोटी इकाई में दर्शाई गई राशि को संबंधित मुद्रा में परिवर्तित करने के लिए गुणक कारक को अपने धन डेटा प्रतिनिधित्व में एकीकृत करना चाहिए।
मुझे लगता है कि आपने पहले ही इसका पता लगा लिया है, आप या तो मूल संख्या, तीसरे पक्ष के मनमाने-सटीक पैकेज या पूर्णांक के साथ काम कर सकते हैं, गणना आपको फ़्लोटिंग-पॉइंट परिणामों तक ले जा सकती है (और करेगी) जिन्हें आपको अपने मौद्रिक के लिए गोल करने की आवश्यकता होगी परिमित परिशुद्धता. एक त्वरित उदाहरण के रूप में कभी भी बहुत अधिक नहीं होता है, मान लें कि आप पूर्णांक मानों को संभालते हैं और 8.5413% (आउच…) की वास्तव में सटीक ब्याज दर के साथ 16k$ का ऋण अनुबंधित करते हैं। फिर आपको 16k$ और अतिरिक्त राशि वापस करनी होगी
1600000 * 0.085413 // amount in cents //Output in cents: 136660.8
मुख्य बात यह है कि गणना के बाद धन राशि की पूर्णांकीकरण प्रक्रिया को ठीक से संभालना है। अधिकांश समय, आपको तीन अलग-अलग प्रकार की राउंडिंग के बीच चयन करना पड़ता है:
"जादुई चटनी" नहीं होती है: आपको अपनी स्थिति के आधार पर मध्यस्थता करने की आवश्यकता होती है। मेरा सुझाव है कि जब आप नई मुद्रा और नए राउंडिंग उपयोग के मामले (रूपांतरण, धन विभाजन, क्रेडिट के लिए ब्याज दरें…) से निपटते हैं तो हमेशा कानून की जांच करें। आगे की परेशानियों से बचने के लिए बेहतर होगा कि आप तुरंत नियमों का पालन करें। उदाहरण के लिए, जब रूपांतरण दरों की बात आती है, तो अधिकांश मुद्राओं ने आवश्यक परिशुद्धता और पूर्णांकन नियमों के बारे में नियम निर्धारित किए हैं (आप यहां EUR रूपांतरण दर नियमों पर एक नज़र डाल सकते हैं)।
निष्कर्ष
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3