एक दशमलव कॉलम में पैसा जमा करना - क्या सटीक और पैमाना?


173

मैं एक डेटाबेस पर धन मूल्यों को संग्रहीत करने के लिए एक दशमलव कॉलम का उपयोग कर रहा हूं, और आज मैं सोच रहा था कि क्या सटीक और उपयोग करने के लिए पैमाने।

चूँकि निश्चित चौड़ाई के चार कॉलम अधिक कुशल होते हैं, मैं सोच रहा था कि दशमलव कॉलम के लिए भी यही सही हो सकता है। क्या यह?

और मुझे किस सटीकता और पैमाने का उपयोग करना चाहिए? मैं सटीक 24/8 सोच रहा था। क्या यह ओवरकिल है, पर्याप्त या ठीक नहीं है?


यह वही है जो मैंने करने का फैसला किया है:

  • ट्रांजेक्शन टेबल में रूपांतरण दरों (जब लागू हो) को एक फ्लोट के रूप में स्टोर करें
  • मुद्रा को खाता तालिका में संग्रहीत करें
  • लेन-देन राशि एक होगी DECIMAL(19,4)
  • रूपांतरण दर का उपयोग करने वाली सभी गणना मेरे आवेदन द्वारा नियंत्रित की जाएंगी ताकि मैं गोल मुद्दों का नियंत्रण रख सकूं

मुझे नहीं लगता कि रूपांतरण दर के लिए एक फ्लोट एक मुद्दा है, क्योंकि यह ज्यादातर संदर्भ के लिए है, और मैं इसे किसी भी तरह एक दशमलव में डालूंगा।

आपके बहुमूल्य इनपुट के लिए आप सभी का धन्यवाद।


2
अपने आप से सवाल पूछें: क्या डेटा को दशमलव रूप में संग्रहीत करना वास्तव में आवश्यक है? कैंट I डेटा को Cents / Pennies -> पूर्णांक के रूप में संग्रहीत करता है?
टेरेंस

5
DECIMAL(19, 4) है एक लोकप्रिय विकल्प जाँच इस भी जाँच यहाँ विश्व मुद्रा का प्रयोग करना है कि कितने दशमलव स्थानों तय करने के लिए, आशा में मदद करता है।
शैजुत

जवाबों:


181

यदि आप एक आकार-फिट-सभी की तलाश कर रहे हैं, तो मेरा सुझाव DECIMAL(19, 4)है कि यह एक लोकप्रिय विकल्प है (एक त्वरित Google इसे समाप्त करता है)। मुझे लगता है कि यह पुराने VBA / Access / Jet Currency data type से उत्पन्न होता है, जो भाषा का पहला निश्चित बिंदु दशमलव प्रकार है; Decimalकेवल VB6 / VBA6 / Jet 4.0 में 'संस्करण 1.0' शैली (यानी पूरी तरह से लागू नहीं) में आया था।

निश्चित बिंदु दशमलव मानों के भंडारण के लिए अंगूठे का नियम कम से कम एक और दशमलव स्थान को स्टोर करना है जितना आपको वास्तव में गोलाई के लिए अनुमति देना है। पुराने Currencyप्रकार की मैपिंग के लिए अंतिम छोर में DECIMAL(19, 4)टाइप करने के पीछे के अंत में टाइप करने का एक कारण यह था कि Currencyप्रकृति द्वारा बैंकरों की गोलाई को प्रदर्शित किया गया था , जबकि DECIMAL(p, s)ट्रंकेशन द्वारा गोल किया गया था।

स्टोरेज के लिए एक अतिरिक्त दशमलव स्थान DECIMALएक वेंडर डिफ़ॉल्ट (और बैंकर्स राउंडिंग को कम से कम कहने के लिए, एक डिजाइनर के लिए। सभी मानों को शून्य से दूर गोल करने की उम्मीद के लिए) लेने के बजाय एक कस्टम गोलाई एल्गोरिदम को लागू करने की अनुमति देता है। ।

हाँ, DECIMAL(24, 8)मुझे ओवरकिल की तरह लगता है। अधिकांश मुद्राओं को चार या पांच दशमलव स्थानों पर उद्धृत किया जाता है। मुझे ऐसी स्थितियों का पता है जहां 8 (या अधिक) का दशमलव पैमाना है की आवश्यकता है, लेकिन यह वह जगह है जहाँ एक 'सामान्य' मौद्रिक राशि (कहते हैं कि चार दशमलव स्थानों) समर्थक rata'd कर दिया गया है, दशमलव परिशुद्धता जिसका अर्थ तदनुसार कम किया जाना चाहिए (यह भी विचार ऐसी परिस्थितियों में एक अस्थायी बिंदु प्रकार)। और किसी के पास आजकल इतना पैसा नहीं है कि उसे 24 की दशमलव सटीकता की आवश्यकता हो :)

हालांकि, एक-आकार-फिट-सभी दृष्टिकोण के बजाय, कुछ शोध क्रम में हो सकते हैं। लेखांकन नियमों के बारे में अपने डिजाइनर या डोमेन विशेषज्ञ से पूछें जो लागू हो सकते हैं: जीएएपी, ईयू, आदि। मैं अस्पष्ट रूप से पाँच दशमलव स्थानों पर गोलाई के लिए स्पष्ट नियमों के साथ कुछ यूरोपीय संघ के अंतर-राज्य स्थानांतरण को याद करता हूं, इसलिए उपयोग कर रहा हूंDECIMAL(p, 6) भंडारण के लिए करना। लेखाकार आमतौर पर चार दशमलव स्थानों का पक्ष लेते हैं।


PS SQL सर्वर के MONEYडेटा प्रकार से बचें क्योंकि यह गोलाई के दौरान अन्य विचारों जैसे कि गोलाई आदि के दौरान सटीकता के साथ गंभीर मुद्दे हैं, एरोन बर्ट्रेंड के ब्लॉग को देखें ।


Microsoft और भाषा डिजाइनरों ने बैंकर के दौर को चुना क्योंकि हार्डवेयर डिजाइनरों ने इसे चुना था [उद्धरण?]। यह उदाहरण के लिए इलेक्ट्रिकल और इलेक्ट्रॉनिक्स इंजीनियर्स संस्थान (IEEE) मानकों में निहित है। और हार्डवेयर डिजाइनरों ने इसे चुना क्योंकि गणितज्ञ इसे पसंद करते हैं। विकिपीडिया देखें ; paraphrase: 1906 के प्रोबबिलिटी और थ्योरी ऑफ एरर्स के संस्करण ने इसे 'कंप्यूटर का नियम' ("कंप्यूटर" का अर्थ है, जो गणना करने वाले मनुष्यों)।


1
इस उत्तर और इस पृष्ठ को और देखें कि भाषा डिजाइनर बैंकर के दौर को क्यों चुनते हैं।
निक चामास

1
onedaywhen: बैंकर की गोलाई माइक्रोसॉफ्ट के कारण नहीं है। @NickChammas: और न ही यह एक भाषा डिजाइनर का आविष्कार है। Microsoft और भाषा डिजाइनरों ने मूल रूप से इसे चुना क्योंकि हार्डवेयर डिजाइनरों ने इसे चुना; उदाहरण के लिए, यह विद्युत और इलेक्ट्रॉनिक्स इंजीनियर्स संस्थान (IEEE) मानकों में निहित है। और हार्डवेयर डिजाइनरों ने इसे चुना क्योंकि गणितज्ञ इसे पसंद करते हैं। En.wikipedia.org/wiki/Rounding#History देखें ; paraphrase: 1906 के प्रोबेबिलिटी और थ्योरी ऑफ एरर्स के संस्करण ने इसे 'कंप्यूटर का नियम' ("कंप्यूटर" का अर्थ है जो मनुष्य गणना करते हैं)।
फोग

9
तो मुझे बिटकॉइन के लिए क्या उपयोग करना चाहिए?
टूलकिट

1
@onedaywhen से DECIMAL(19, 4)अधिक लोकप्रिय क्यों है DECIMAL(19, 2)? अधिकांश विश्व मुद्राएँ केवल दो दशमलव स्थान हैं।
कोकडे

3
@ zypA13510: हाँ, मेरा दावा दस साल पहले का है! लेकिन यह जवाब के लिए मेरा तीसरा सबसे अधिक वोट दिया गया है और मेरे एसओ प्रतिनिधि के रूप में परिवर्तन का एक अच्छा हिस्सा के लिए खातों है तो मैं में quids हूँ :)
onedaywhen

105

हमने हाल ही में एक प्रणाली लागू की है जिसमें कई मुद्राओं में मूल्यों को संभालने और उनके बीच बदलने की आवश्यकता है, और कुछ चीजों को कठिन तरीके से समझ लिया है।

कभी पैसे के लिए फर्श का उपयोग करने वालों का उपयोग करें

फ्लोटिंग पॉइंट अंकगणित में अशुद्धि का परिचय दिया जाता है, जिस पर तब तक ध्यान नहीं दिया जा सकता, जब तक कि उन्होंने कुछ खराब न कर दिया हो। सभी मानों को पूर्णांक या निश्चित-दशमलव प्रकार के रूप में संग्रहीत किया जाना चाहिए, और यदि आप एक निश्चित-दशमलव प्रकार का उपयोग करना चुनते हैं, तो सुनिश्चित करें कि आप ठीक से समझते हैं कि यह प्रकार हुड के नीचे क्या करता है (यानी, क्या यह आंतरिक रूप से पूर्णांक या फ्लोटिंग बिंदु का उपयोग करता है प्रकार)।

जब आपको गणना या रूपांतरण करने की आवश्यकता हो:

  1. मूल्यों को फ्लोटिंग पॉइंट में बदलें
  2. नए मान की गणना करें
  3. संख्या को गोल करें और इसे एक पूर्णांक में बदलें

चरण 3 में एक पूर्णांक संख्या में एक फ्लोटिंग पॉइंट संख्या को परिवर्तित करते समय, बस इसे मत डालें - इसे गोल करने के लिए गणित फ़ंक्शन का उपयोग करें। यह आमतौर पर होगा round, हालांकि विशेष मामलों में यह floorया हो सकता है ceil। अंतर को जानें और ध्यान से चुनें।

मान के साथ संख्या का प्रकार संग्रहीत करें

यह आपके लिए उतना महत्वपूर्ण नहीं हो सकता है यदि आप केवल एक मुद्रा को संभाल रहे हैं, लेकिन कई मुद्राओं को संभालने में यह हमारे लिए महत्वपूर्ण था। हमने मुद्रा के लिए 3-वर्ण कोड का उपयोग किया, जैसे कि USD, GBP, JPY, EUR, आदि।

स्थिति के आधार पर, यह स्टोर करने में भी मददगार हो सकता है:

  • कर के पहले या बाद में संख्या है (या कर की दर क्या थी)
  • क्या संख्या रूपांतरण का परिणाम है (और इसे किससे रूपांतरित किया गया था)

उन संख्याओं की सटीकता सीमा जानें, जिनसे आप निपट रहे हैं

वास्तविक मूल्यों के लिए, आप मुद्रा की सबसे छोटी इकाई के समान सटीक होना चाहते हैं। इसका मतलब यह है कि आपके पास एक प्रतिशत से भी छोटा कोई मूल्य नहीं है, एक पैसा, एक येन, एक फेन आदि, बिना किसी कारण के उच्च सटीकता के साथ मूल्यों को संग्रहीत न करें।

आंतरिक रूप से, आप छोटे मूल्यों से निपटने के लिए चुन सकते हैं, जिस स्थिति में यह एक अलग प्रकार का मुद्रा मूल्य है । सुनिश्चित करें कि आपका कोड जानता है कि कौन सा है और उन्हें मिलाया नहीं जाता है। यहां तक ​​कि फ्लोटिंग पॉइंट वैल्यू का उपयोग करने से बचें।


उन सभी नियमों को एक साथ जोड़ते हुए, हमने निम्नलिखित नियमों पर निर्णय लिया। रनिंग कोड में, मुद्राओं को सबसे छोटी इकाई के लिए पूर्णांक का उपयोग करके संग्रहीत किया जाता है।

class Currency {
   String code;       //  eg "USD"
   int value;         //  eg 2500
   boolean converted;
}

class Price {
   Currency grossValue;
   Currency netValue;
   Tax taxRate;
}

डेटाबेस में, मानों को निम्न प्रारूप में एक स्ट्रिंग के रूप में संग्रहीत किया जाता है:

USD:2500

यह $ 25.00 का मूल्य संग्रहीत करता है। हम ऐसा केवल इसलिए कर पाए क्योंकि मुद्राओं से संबंधित कोड को डेटाबेस लेयर के भीतर होने की आवश्यकता नहीं है, इसलिए सभी मानों को पहले मेमोरी में परिवर्तित किया जा सकता है। अन्य स्थितियों में कोई संदेह नहीं है कि अन्य समाधानों के लिए खुद को उधार देना होगा।


और अगर मैं इसे पहले स्पष्ट नहीं कर पाया, तो फ्लोट का उपयोग न करें!


1
कभी मत कहो: कभी-कभी पैसे की मात्रा प्रो rata'd होती है और बाद में फिर से जोड़ने की आवश्यकता होती है। उदाहरण: प्रति शेयर शुद्ध देने के लिए इश्यू (अपेक्षाकृत छोटे) में कुल शेयरों की संख्या से विभाजित कुल लाभांश (अपेक्षाकृत छोटा)। कभी-कभी फ्लोट राउंड बेहतर होता है :)
onedaywhen

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

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

1
@onedaywhen प्रति शेयर के मामलों में नेट, आप प्रो-रटा रकम की राशि और मूल कुल की तुलना कर सकते हैं और शेष (जब दशमलव / पूर्णांक प्रकारों का उपयोग करके) से निपटने के लिए एक रणनीति तैयार कर सकते हैं।
शिव

2
bigintयदि आप राशि के अनुसार छांटना चाहते हैं, तो माईस्क्ल के लिए, मैं पूर्णांक (2500) को संग्रहीत करने की सलाह देता हूं । और बड़े पूर्णांकों के साथ काम करते समय PHP 32bit के साथ अपना समय बर्बाद न करें, 64bit या Node.JS पर अपग्रेड करें;)
रिकी बॉयस

4

MySQL में पैसे संभालते समय, DECIMAL (13,2) का उपयोग करें यदि आप अपने पैसे के मूल्यों की शुद्धता जानते हैं या यदि आप एक त्वरित अच्छा-पर्याप्त अनुमानित मूल्य चाहते हैं तो DOUBLE का उपयोग करें। तो अगर आपके आवेदन को एक ट्रिलियन डॉलर (या यूरो या पाउंड) तक के धन मूल्यों को संभालने की आवश्यकता है, तो यह काम करना चाहिए:

DECIMAL(13, 2)

या, यदि आपको GAAP का अनुपालन करने की आवश्यकता है तो उपयोग करें:

DECIMAL(13, 4)

3
क्या आप 2500 पृष्ठ दस्तावेज़ की सामग्री के बजाय GAAP दिशानिर्देशों के विशिष्ट भाग से लिंक कर सकते हैं ? धन्यवाद।
ReactingToAngularVues

@ReactingToAngularVues ऐसा लगता है कि पृष्ठ बदल गया है। क्षमा करें
pollux1er

2

4 दशमलव स्थान आपको दुनिया की सबसे छोटी मुद्रा उप-इकाइयों को संग्रहीत करने की सटीकता प्रदान करेंगे। आप इसे और नीचे ले जा सकते हैं यदि आपको माइक्रोप्रिमेंट (नैनोपायमेंट?) सटीकता की आवश्यकता है।

मैं भी DECIMALDBMS- विशिष्ट पैसे प्रकारों को पसंद करता हूं, आप उस तरह के तर्क को IMO में सुरक्षित रख रहे हैं। एक ही लाइनों के साथ एक और दृष्टिकोण बस एक [लंबे] पूर्णांक का उपयोग करना है, आवेदन स्तर पर किए गए मानव पठनीयता (¤ = मुद्रा प्रतीक) के लिए ¤unit.subunit में प्रारूपण के साथ।


1

एसक्यूएल सर्वर पर पैसा डेटाटाइप में दशमलव के बाद चार अंक होते हैं।

SQL Server 2000 पुस्तकें ऑनलाइन से:

मौद्रिक डेटा सकारात्मक या नकारात्मक मात्रा में धन का प्रतिनिधित्व करता है। Microsoft® SQL Server ™ 2000 में, मौद्रिक डेटा को धन और छोटे डेटा प्रकारों का उपयोग करके संग्रहीत किया जाता है। मौद्रिक डेटा को चार दशमलव स्थानों की सटीकता के लिए संग्रहीत किया जा सकता है। +922,337,203,685,477.5808 से +922,337,203,685,477.5807 के माध्यम से सीमा में मूल्यों को संग्रहीत करने के लिए मनी डेटा प्रकार का उपयोग करें (एक मूल्य को संग्रहीत करने के लिए 8 बाइट की आवश्यकता होती है)। 214,748.3647 के माध्यम से -214,748.3648 से मान में स्टोर करने के लिए छोटे डेटा प्रकार का उपयोग करें (एक मूल्य को संग्रहीत करने के लिए 4 बाइट की आवश्यकता होती है)। यदि दशमलव स्थानों की अधिक संख्या आवश्यक है, तो इसके बजाय दशमलव डेटा प्रकार का उपयोग करें।


1

कभी-कभी आपको एक प्रतिशत से भी कम जाने की आवश्यकता होगी और ऐसी अंतर्राष्ट्रीय मुद्राएँ हैं जो बहुत बड़े प्रदर्शनों का उपयोग करती हैं। उदाहरण के लिए, आप अपने ग्राहकों से प्रति लेनदेन 0.088 सेंट वसूल सकते हैं। मेरे Oracle डेटाबेस में कॉलम को NUMBER (20,4) के रूप में परिभाषित किया गया है


1

यदि आप DB में किसी भी प्रकार के अंकगणितीय संक्रियाएँ करने जा रहे हैं (बिलिंग दरों को बढ़ाना और इतने पर), तो आप शायद उन लोगों की तुलना में अधिक सटीक जानकारी चाहते हैं जो यहाँ सुझा रहे हैं, उन्हीं कारणों से जो आप कभी नहीं करेंगे। अनुप्रयोग कोड में एक डबल-सटीक फ़्लोटिंग पॉइंट मान से कम का उपयोग करना चाहते हैं।


यही मैं सोच रहा था, लेकिन मुद्रा दरों के संदर्भ में (यानी, जोम्बो डॉलर को USD में परिवर्तित करना)। मैं उन डेटाबेस पर कुछ प्रयोग करूँगा जो मैं (psql, sqlite) का उपयोग कर रहा हूँ, यह देखने के लिए कि वे बहुत छोटे दशमलव पर गोलाई को कैसे संभालते हैं।
इवान

इसके अलावा, कुछ dbms / भाषाओं में सटीकता की समस्या नहीं है?
इवान

2
सभी भाषाओं में सटीकता की समस्या है।
मार्कस डाउनिंग

इन दिनों सबसे आम सिफारिश मनमाना परिशुद्धता (विचार BigDecimal) का उपयोग करने के लिए है , लेकिन लंबे समय तक यह डबल-परिशुद्धता ( doubleइसके बजाय सोचें float) था। इसके अलावा, कुछ मामलों में मनमानी परिशुद्धता में महत्वपूर्ण प्रदर्शन दंड है। परीक्षण निश्चित रूप से सही दृष्टिकोण है।
हांक गे

0

यदि आप IBM Informix डायनेमिक सर्वर का उपयोग कर रहे थे, तो आपके पास एक MONEY प्रकार होगा जो DECIMAL या NUMERIC प्रकार पर एक छोटा संस्करण है। यह हमेशा एक निश्चित-बिंदु प्रकार होता है (जबकि DECIMAL एक अस्थायी बिंदु प्रकार हो सकता है)। आप 1 से 32 तक के पैमाने को निर्दिष्ट कर सकते हैं, और 0 से 32 की परिशुद्धता (16 के पैमाने पर डिफ़ॉल्ट और 2 की सटीकता के लिए) को निर्दिष्ट कर सकते हैं। इसलिए, आपको जो स्टोर करने की आवश्यकता है, उसके आधार पर, आप DECIMAL (16,2) का उपयोग कर सकते हैं - अभी भी यूएस फेडरल डेफिसिट को पास के प्रतिशत तक रखने के लिए पर्याप्त बड़ा है - या आप एक छोटी रेंज, या अधिक दशमलव स्थानों का उपयोग कर सकते हैं।


0

मुझे लगता है कि एक बड़े हिस्से के लिए आपके या आपके ग्राहक की आवश्यकताओं को निर्धारित करना चाहिए कि क्या सटीक और पैमाने का उपयोग करना है। उदाहरण के लिए, ई-कॉमर्स वेबसाइट के लिए मैं केवल GBP में पैसे के सौदे पर काम कर रहा हूं, मुझे इसे दशमलव (6, 2) पर रखना आवश्यक है।


0

यहां एक देर से जवाब, लेकिन मैंने उपयोग किया है

DECIMAL(13,2)

जो मैं सोच में सही हूँ उसे 99,999,999,999.99 तक अनुमति देनी चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.