जावा में मौद्रिक मूल्यों का प्रतिनिधित्व [बंद]


94

मैं समझता हूँ कि BigDecimal जावा में मौद्रिक मूल्यों का प्रतिनिधित्व करने के लिए सर्वोत्तम अभ्यास की सिफारिश की जाती है। तुम क्या इस्तेमाल करते हो? क्या एक बेहतर पुस्तकालय है जिसे आप इसके बजाय उपयोग करना पसंद करते हैं?



1
यहाँ एक मुद्रा वर्ग है जिसे आप कॉपी और विस्तारित कर सकते हैं: java-articles.info/articles/?p=254
गिल्बर्ट ले ब्लैंक

जवाबों:


81

BigDecimalसब तरह से। मैंने कुछ लोगों को अपने स्वयं के Cashया Moneyकक्षाएं बनाने के बारे में सुना है जो मुद्रा के साथ एक नकद मूल्य को अलग करते हैं, लेकिन त्वचा के नीचे यह अभी भी एक है BigDecimal, शायद साथBigDecimal.ROUND_HALF_EVEN गोलाई के ।

संपादित करें: जैसा कि डॉन ने अपने उत्तर में उल्लेख किया है , टाइमएंडमनी जैसी खुली खट्टी परियोजनाएं हैं , और डेवलपर्स को पहिया को सुदृढ़ करने से रोकने की कोशिश करने के लिए मैं उनकी सराहना करता हूं, मुझे अभी प्री-अल्फा लाइब्रेरी का उपयोग करने के लिए पर्याप्त आत्मविश्वास नहीं है यह उत्पादन के माहौल में है। इसके अलावा, यदि आप हुड के नीचे खुदाई करते हैं, तो आप देखेंगे कि वे BigDecimalभी उपयोग करते हैं


4
+1। हमने एक कंटेनर वर्ग जोड़ने का फैसला किया है जो एक मुद्रा का उपभोग करता है, भी। यह तब काम आता है जब तालिकाओं में मौद्रिक मूल्यों का प्रतिपादन किया जाता है।
डैनियल हिलर

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

3
@ninesered एक शानदार उदाहरण देता है कि क्यों अपना खुद का रोल करना एक बुरा जवाब है। "ओह, और वैसे, यह $ CURRENCY_X के लिए काम नहीं करता है।" यह एक अच्छा संकेत है कि यह कई अन्य मुद्राओं के लिए भी काम नहीं करता है।
जेम्स मूर

1
@JamesMoore मैं असहमत हूं कि "अपना खुद का रोल करना" एक बुरा दृष्टिकोण है, आपको बस उस दृष्टिकोण की संभावित सीमाओं से अवगत होना होगा जो आप चुनते हैं, इसलिए मेरे लिए इसका उल्लेख करने का कारण। प्रति मुद्रा में अलग-अलग गोलाई नियमों को लागू करना तुच्छ है, लेकिन यदि आपके सिस्टम को केवल USD या EUR में सौदा करने की आवश्यकता है, तो आपको इंजीनियर चीजों से अधिक की आवश्यकता नहीं है।
14

1
पर एक नजर डालें stackoverflow.com/questions/5134237/... सिर्फ एक कारण है कि BigDecimal एक समस्या है के लिए। प्लैनेट-वाइड अकाउंटिंग केवल विशेष मामलों का एक दलदल है, और बिगडीकल के गलीचा के नीचे उन सभी को स्वीप करने की कोशिश करना बस काम नहीं करता है।
जेम्स मूर

52

यह JodaMoney के बारे में जानने के लिए खोज इंजन द्वारा यहां पहुंचने वाले लोगों के लिए उपयोगी हो सकता है: http://www.joda.org/joda-money/


धन्यवाद। मुझे जोडा मनी के बारे में फॉलो-अप नोट जोड़ने का मतलब है। क्या आपने इसका इस्तेमाल किया है?
dshw

2
+1 रुचिकर लगता है, यह देखकर खुशी होती है कि यह BigDecimalहुड के नीचे है!
ninesided


8

एक सुविधाजनक पुस्तकालय जो मैंने पहले चलाया था, वह है जोडा-मनी लाइब्रेरी। इसका एक कार्यान्वयन वास्तव में बिगडेसीमल पर आधारित है। यह ISO-4217 पर आधारित है मुद्राओं के लिए विनिर्देश और एक अनुकूलित मुद्रा सूची (CVS के माध्यम से लोड) का समर्थन कर सकता है।

इस लाइब्रेरी में कम संख्या में ऐसी फाइलें हैं, जिनमें से संशोधनों की आवश्यकता होने पर व्यक्ति जल्दी से जा सकता है। जोडा-मनी अपाचे 2.0 लाइसेंस के तहत प्रकाशित किया जाता है।


7

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

किसी भी तरह से, मैं शायद वर्ग का विस्तार एक .toString () में कर सकता हूं जो सही प्रारूप का उपयोग करता है, और अन्य तरीकों को रखने के लिए एक जगह के रूप में जो ऊपर आ सकता है (यदि लंबे समय तक, गुणा और विभाजन करना दशमलव हो जाएगा 't समायोजित)

इसके अलावा, यदि आप अपने स्वयं के वर्ग और इंटरफ़ेस को परिभाषित करते हैं, तो आप कार्यान्वयन को वसीयत में बदल सकते हैं।


2
बाहर देखो, यहां तक ​​कि लंबे समय तक सेंट में यूएस फेडरल डेट रखने के लिए बहुत कम हो सकता है ... यदि अब नहीं तो कुछ वर्षों में।
इंगो

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

3

BigDecimal या अन्य निश्चित बिंदु प्रतिनिधित्व वह है जो आम तौर पर पैसे के लिए आवश्यक होता है।

फ्लोटिंग पॉइंट ( Double, Float) निरूपण और परिकलन अक्षम्य हैं, जिससे गलत परिणाम सामने आते हैं।


7
कड़े शब्दों में, बिगडेक्मल भी अक्षम है; यह सिर्फ दशमलव गोलाई के साथ बेहतर है जो हम दैनिक जीवन में उपयोग करते हैं, और आपको गोलाई मोड निर्दिष्ट करने की अनुमति देता है।
माइकल बोर्गवर्ड

1
@Michael Borgwardt BigDecimal IEEE FP से भिन्न है जिसमें एक स्पष्ट पैमाने निर्दिष्ट है। हालांकि सभी ऑपरेशन सटीक नहीं होते हैं, यह सुनिश्चित करता है कि संचालन और व्यवहार का एक सेट हमेशा सटीक होता है और स्केल स्थिर होता है जबकि IEEE FP के लिए मान मूल्य के साथ घट जाता है।

1
पैसे का क्या करना है? दुनिया भर के लेखांकन संगठनों में आमतौर पर बहुत विशिष्ट आवश्यकताएं होती हैं कि आप उनकी मुद्रा में गणित कैसे करते हैं। क्या BigDecimal इन मानकों में से हर एक का सटीक मिलान करता है? क्या अगले साल ऐसा होगा, जब वे मानक बदल जाएंगे? और BigDecimal मुद्राओं के लिए उपयोगी गोलाई नियमों को निर्दिष्ट करने के करीब भी नहीं आता है।
जेम्स मूर

2

समय और धन के साथ व्यवहार करते समय आपको इतना सावधान रहना होगा।

जब आप पैसे के साथ काम कर रहे हों, तो मुझे उम्मीद है कि हर किसी को कभी भी फ्लोट या डबल का उपयोग नहीं करना चाहिए।

लेकिन मैं BigDecimal को लेकर अनिश्चित हूं।

ज्यादातर मामलों में अगर आप सिर्फ एक इंट या लंबे समय में सेंट का ट्रैक रखते हैं तो आप ठीक हो जाएंगे। इस तरह आप एक दशमलव स्थान से कभी नहीं निपटते।

जब आप इसे प्रिंट करते हैं तो आप केवल डॉलर प्रदर्शित करते हैं। हमेशा पूर्णांक का उपयोग करके आंतरिक के साथ काम करते हैं। यदि यह विभाजित करने की आवश्यकता है या Math.abs () का उपयोग करने की आवश्यकता है तो यह मुश्किल हो सकता है।

हालाँकि, आप आधा प्रतिशत, या यहाँ तक कि एक प्रतिशत का भी ध्यान रख सकते हैं। मुझे नहीं पता कि ऐसा करने का एक अच्छा तरीका क्या है। आपको बस हज़ारों सेंट से निपटने और लंबे समय तक उपयोग करने की आवश्यकता हो सकती है। या शायद आप BigDecimal का उपयोग करने के लिए मजबूर हो जाएंगे

मैं इस पर और भी बहुत कुछ पढ़ूंगा, लेकिन हर उस व्यक्ति को नजरअंदाज कर दूंगा जो पैसे का प्रतिनिधित्व करने के लिए फ्लोट या डबल का इस्तेमाल करने की बात करने लगता है। वे सिर्फ परेशानी पूछ रहे हैं।

मुझे लगता है कि मेरी सलाह पूरी नहीं हुई है, इसलिए कृपया इसे और अधिक में डालें। आप खतरनाक प्रकारों से निपट रहे हैं!


2
आपको BigDecimal का उपयोग करने के लिए "मजबूर" होने की आवश्यकता क्यों होगी? आप किस बारे में अनिश्चित हैं? यह सेंट के साथ काम करने के लिए स्पष्ट रूप से बेहतर है, क्योंकि यह आपको गोल मोड को स्पष्ट रूप से निर्दिष्ट करने की अनुमति देता है।
माइकल बोर्गवर्ड

1
@MichaelBorgwardt: हाँ, यह आपको उन राउंडिंग मोड्स की एक छोटी सबसेट निर्दिष्ट करने की अनुमति देता है जो आपको मुद्राओं के लिए चाहिए। इसलिए? (संकेत:। मुद्राओं गोलाई का फैसला किया है, आम तौर पर, राष्ट्रीय लेखा संगठनों द्वारा वे पूरी तरह से अजीब विशेष मामलों में टॉस के लिए खुश हैं देखें। Stackoverflow.com/questions/5134237/... क्यों BigDecimal राउंडिंग पूरी तरह से है बस के लिए कई मनोरंजक किसी एक कारण से यहाँ बेकार।)
जेम्स मूर

@ नाम: यह वास्तव में "बेकार" कैसे है? बिगडेसिमल के साथ थोस विशेष मामलों को लागू करना कुछ और के साथ कैसे कठिन होगा?
माइकल बोर्गवर्ड 16

1
ठीक है, पूरी तरह से बेकार बहुत मजबूत है। मुद्रा का सार करने वाले जटिल वर्ग में, बिगडेसिमल के गोलाई नियम संभवतः कुछ विशिष्ट उदाहरणों में उपयोगी होते हैं, जिस तरह से मुद्रा गोलाई होती है। लेकिन सामान्य मामला यह है कि मुद्राओं के लिए राउंडिंग नियमों में ऐसे तंत्रों की आवश्यकता होती है जो समय के साथ बदलने के अधीन होते हैं (चूंकि मानव लेखा एजेंसियां ​​नियम बनाती हैं, और उन्हें बदलने के लिए स्वतंत्र हैं)। सवाल यूरो के बारे में नहीं है (या जो अगले महीने यूरो की जगह लेता है ...), या डॉलर 2011 में, यह मुद्रा के बारे में है, इसलिए आपको बहुत सारे जटिल जटिलता से निपटना होगा।
जेम्स मूर

2

मनी क्लास बनाना एक रास्ता है। नीचे BigDecimal (या यहां तक ​​कि एक इंट) का उपयोग करना। फिर गोलाई सम्मेलन को परिभाषित करने के लिए मुद्रा वर्ग का उपयोग करना।

दुर्भाग्य से ऑपरेटर ओवरलोडिंग के बिना जावा इस तरह के मूल प्रकारों को बनाने में काफी अप्रिय बनाता है।


2

एक बेहतर पुस्तकालय है, टिम्डमनी । आईएमओ, यह इन 2 अवधारणाओं का प्रतिनिधित्व करने के लिए जेडीके द्वारा प्रदान की गई पुस्तकालयों से बहुत बेहतर है।


3
यह उत्तर तीन साल पहले पोस्ट किया गया था। आज, उस लिंक के अनुसार टाइमएंडमनी परियोजना अभी भी पूर्व-अल्फ़ा है।
जेम्स मूर

1
@JamesMoore अच्छा फोन। जवाब अब 7 साल का है और परियोजना अभी भी स्थिर नहीं है।
नवीन

1

निश्चित रूप से बिगडेसिमल नहीं। गोलाई और प्रस्तुति के लिए बहुत सारे विशेष नियम हैं जिनके बारे में आपको चिंता करनी होगी।

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


6
और उसका मनी क्लास का अंतर्निहित डेटा प्रकार? BigDecimal।
नौ

1
यह सच नहीं है। आप इंटगर को मनी क्लास में इस्तेमाल कर सकते हैं, जो मार्टिन करता है। मैंने कई बार ऐसा किया है।
एगर्वारी

सिफारिश हालांकि सही है; धन से जुड़े गणना विशेष मामलों का एक बड़ा दलदल है जो समय के साथ बदलते हैं। BigDecimal समाधान के एक छोटे हिस्से के रूप में उपयोगी हो सकता है, लेकिन यह निश्चित रूप से सामान्य नहीं है।
जेम्स मूर

1

अरे, बिगडेक्मल पर यहां एक बहुत ही दिलचस्प लेख है, और इसका उदाहरण है कि कभी-कभी डबल्स के बजाय इसका उपयोग क्यों किया जाता है। BigDecimal Tutorial


0

जब आप अंततः एक मुद्रा मूल्य प्रदर्शित करते हैं तो आप DecimalFormat वर्ग का उपयोग कर सकते हैं। यह स्थानीयकरण का समर्थन प्रदान करता है और यह बहुत ही एक्स्टेंसिबल है।


0

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

   assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));

0

इसमें हमेशा अड़चनें और विशिष्टताएँ शामिल होती हैं। निम्नलिखित लेख में उल्लिखित सूक्ष्म मुद्दों की सराहना करने के लिए पर्याप्त अनुभव के बिना किसी को भी वास्तविक विश्व वित्तीय डेटा से निपटने से पहले गंभीरता से पुनर्विचार करना चाहिए:

http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money

BigDecimal शायद ही सही प्रतिनिधित्व या पहेली का एकमात्र टुकड़ा है। कुछ शर्तों को देखते हुए, पूर्णांक के रूप में संग्रहीत सेंट द्वारा समर्थित मनी क्लास का उपयोग करना पर्याप्त हो सकता है और बिगडेसीमल की तुलना में बहुत तेज होगा। हां, इसका अर्थ है कि डॉलर का उपयोग मुद्रा के रूप में होता है और मात्राओं को सीमित करता है, लेकिन ऐसे अवरोध कई उपयोग के मामलों के लिए पूरी तरह से स्वीकार्य हैं और सभी मुद्राओं में वैसे भी गोल और उप-संप्रदायों के लिए विशेष मामले हैं, इसलिए कोई "सार्वभौमिक" समाधान नहीं है।


1
यह वास्तविक उत्तर के बजाय किसी अन्य पोस्ट पर एक टिप्पणी लगती है। यह अत्यधिक विट्रियोलिक भी है। कृपया भविष्य में और अधिक नागरिक बनने की कोशिश करें।
स्लाटर विक्टोरॉफ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.