2008-11-12 11 views
85

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

+3

[जेएसआर 354] (http://jcp.org/en/jsr/detail?id=354) – yegor256

+1

पर एक नज़र डालें यहां एक मुद्रा वर्ग है जिसे आप कॉपी और विस्तारित कर सकते हैं: http: // java-articles। जानकारी/लेख /? पी = 254 –

+0

जेएसआर -354 https: // github के संदर्भ कार्यान्वयन को भी देखें।कॉम/जावामोनी/जेएसआर 354-ri – beat

उत्तर

74

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

संपादित करें: डॉन his answer में उल्लेख है, वहाँ timeandmoney की तरह खुले sourced परियोजनाओं रहे हैं, और जबकि मैं उन्हें पहिया बदलने की होने से डेवलपर्स को रोकने की कोशिश कर के लिए सराहना, मैं सिर्फ एक पूर्व में पर्याप्त आत्मविश्वास की जरूरत नहीं है -फाफा लाइब्रेरी इसे उत्पादन वातावरण में उपयोग करने के लिए। इसके अलावा, यदि आप हुड के नीचे चारों ओर खुदाई करते हैं, तो आप they use BigDecimal too देखेंगे।

+4

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

+1

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

+3

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

3

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

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

+7

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

+0

@ माइकल बोर्गवर्ड बिगडिसीमल आईईईई एफपी से अलग है जिसमें एक स्पष्ट पैमाने निर्दिष्ट किया गया है। हालांकि सभी परिचालन सटीक नहीं हैं, यह सुनिश्चित करता है कि संचालन और व्यवहार का एक सेट हमेशा * सटीक है और स्केल * स्थिर * है जबकि आईईईई एफपी के लिए पैमाने मूल्य के साथ घटता है। –

+1

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

7

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

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

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

+2

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

+3

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

2

आपको समय और धन से निपटने के दौरान बहुत सावधान रहना होगा।

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

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

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

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

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

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

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

+2

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

+1

@ माइकलबोर्गवर्ड: हाँ, यह आपको मुद्राओं के लिए आवश्यक राउंडिंग मोड का एक छोटा सबसेट निर्दिष्ट करने की अनुमति देता है। इसलिए? (संकेत: राउंडिंग मुद्राएं आमतौर पर राष्ट्रीय लेखा संगठनों द्वारा तय की जाती हैं। वे अजीब विशेष मामलों में टॉस करने के लिए पूरी तरह से खुश हैं। Http://stackoverflow.com/questions/5134237/swiss-and-argentinian-currency-fourth- बिगडिसीमल राउंडिंग पूरी तरह से बेकार क्यों है, इसके कई मनोरंजक कारणों में से केवल एक के लिए दशमलव-अंक-राउंडिंग।) –

+0

@ जेम्स: यह "बेकार" कितना है? कुछ विशेषताओं के मुकाबले बिगडिसिल के साथ विशेष मामलों को कैसे लागू किया जाएगा? –

2

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

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

2

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

+3

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

+1

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

1

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

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

+6

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

+1

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

+0

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

0

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

0

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

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

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

+0

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

+2

+1 दिलचस्प लग रहा है, यह देखने के लिए खुश है कि यह 'बिगडिसीमल' हुड के नीचे है! – ninesided

1

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

8

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

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

0

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

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

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

+1

यह वास्तविक उत्तर की बजाय किसी अन्य पोस्ट पर एक टिप्पणी प्रतीत होता है। यह भी अत्यधिक विट्रियल है। भविष्य में अधिक नागरिक होने का प्रयास करें। –

+0

उचित बिंदु, संपादित। – Craig

संबंधित मुद्दे