2008-08-11 19 views
42

का उपयोग हाल ही में मैंने java.math.MathContext के उपयोग को समझने की कोशिश की लेकिन ठीक से समझने में असफल रहा। क्या यह java.math.BigDecimal में घूमने के लिए प्रयोग किया जाता है, यदि हां, तो यह दशमलव अंकों को क्यों नहीं बल्कि मनीसा भाग भी लेता है।java.math.MathContext

एपीआई दस्तावेज़ों से, मुझे पता चला कि यह ANSI X3.274-1996 और ANSI X3.274-1996/AM 1-2000 विनिर्देशों में निर्दिष्ट मानक का पालन करता है लेकिन मुझे उन्हें ऑनलाइन पढ़ने के लिए नहीं मिला।

अगर आपको इस पर कोई विचार है तो कृपया मुझे बताएं।

उत्तर

35

@jatan

धन्यवाद आप के लिए जवाब। यह समझ में आता है। क्या आप कृपया BigDecimal # राउंड विधि के संदर्भ में MathContext को समझा सकते हैं।

के बारे में BigDecimal.round()बनाम किसी अन्य BigDecimal विधि विशेष कुछ भी नहीं है। सभी मामलों में, MathContext महत्वपूर्ण अंकों और राउंडिंग तकनीक की संख्या निर्दिष्ट करता है। असल में, प्रत्येक MathContext के दो भाग हैं। एक परिशुद्धता है, और RoundingMode भी है।

सटीक फिर से महत्वपूर्ण अंकों की संख्या निर्दिष्ट करता है। इसलिए यदि आप 123 को एक संख्या के रूप में निर्दिष्ट करते हैं, और 2 महत्वपूर्ण अंक मांगते हैं, तो आपको 120 मिल जाएगा। यदि आप वैज्ञानिक नोटेशन के संदर्भ में सोचते हैं तो यह स्पष्ट हो सकता है।

123 वैज्ञानिक नोटेशन में 1.23e2 होगा। यदि आप केवल 2 महत्वपूर्ण अंक रखते हैं, तो आपको 1.2e2, या 120 मिलते हैं। महत्वपूर्ण अंकों की संख्या को कम करके, हम परिशुद्धता को कम करते हैं जिसके साथ हम एक संख्या निर्दिष्ट कर सकते हैं।

RoundingMode भाग निर्दिष्ट करता है कि हमें परिशुद्धता के नुकसान को कैसे संभालना चाहिए। उदाहरण का पुन: उपयोग करने के लिए, यदि आप संख्या के रूप में 123 का उपयोग करते हैं, और 2 महत्वपूर्ण अंकों के लिए पूछते हैं, तो आपने अपनी परिशुद्धता कम कर दी है। HALF_UP (डिफ़ॉल्ट मोड) के साथ, 123120 बन जाएगा। CEILING के के साथ, आपको 130 मिल जाएगा।

उदाहरण के लिए:

System.out.println(new BigDecimal("123.4", 
        new MathContext(4,RoundingMode.HALF_UP))); 
System.out.println(new BigDecimal("123.4", 
        new MathContext(2,RoundingMode.HALF_UP))); 
System.out.println(new BigDecimal("123.4", 
        new MathContext(2,RoundingMode.CEILING))); 
System.out.println(new BigDecimal("123.4", 
        new MathContext(1,RoundingMode.CEILING))); 

आउटपुट:

123.4 
1.2E+2 
1.3E+2 
2E+2 

आप देख सकते हैं कि दोनों परिशुद्धता और राउंडिंग मोड उत्पादन प्रभावित करते हैं।

+0

क्या '123.4' प्रारूपित करने के लिए '123.4' प्रारूपित करने का कोई तरीका है' 120' जैसी स्ट्रिंग में परिणाम? यह 2 महत्वपूर्ण आंकड़े हैं (जैसा कि '1.2E2' है) क्योंकि पीछे की ओर शून्य होने तक महत्वपूर्ण आंकड़ों को पुनर्प्राप्त करने में पीछे शून्यों को पारंपरिक रूप से शामिल नहीं किया जाता है। और मेरे उद्देश्यों के लिए, यदि प्रारूपित करने की संख्या '103.4' थी, तो मुझे परवाह नहीं है कि आप परिणामस्वरूप' 100' संख्या में 2 सिग अंजीर नहीं बता सकते हैं। मैं सिर्फ संख्याओं के सरल/क्लीनर देखना चाहता हूं। – hepcat72

4

यदि मैं आपको सही ढंग से समझ रहा हूं, तो ऐसा लगता है कि आप MathContext को दशमलव बिंदु के बाद कितने अंकों को रखा जाना चाहिए, यह नियंत्रित करने की अपेक्षा कर रहे हैं। ऐसा नहीं है कि यह क्या है। यह निर्दिष्ट करता है कि कितने अंक रखना है, कुल। इसलिए यदि आप निर्दिष्ट करते हैं कि आप 3 महत्वपूर्ण अंक चाहते हैं, तो यह सब कुछ आपको मिल जाएगा।

उदाहरण के लिए

, इस:

System.out.println(new BigDecimal("1234567890.123456789", 
        new MathContext(20))); 

System.out.println(new BigDecimal("1234567890.123456789", 
        new MathContext(10))); 

System.out.println(new BigDecimal("1234567890.123456789", 
        new MathContext(5))); 

इच्छा उत्पादन:

1234567890.123456789 
1234567890 
1.2346E+9 
+1

धन्यवाद। मैं दशमलव के बाद कितने अंक रखना चाहूंगा? – Drew

+1

यह वास्तव में BigDecimal के लिए एक सवाल नहीं है। BigDecimal के साथ, आपको इसके बजाय महत्वपूर्ण अंकों की संख्या निर्दिष्ट करनी चाहिए। प्रदर्शन के लिए स्वरूपण करते समय दशमलव बिंदु के बाद कितने अंक निर्धारित किए जाने चाहिए। आप इसे String.format() या DecimalFormat.format() के साथ नियंत्रित कर सकते हैं। –

+0

@ ड्रू मुझे लगता है कि आप [BigDecimal.setScale] का उपयोग कर सकते हैं (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/math/BigDecimal.java# BigDecimal.setScale% 28int% 2Cjava.math.RoundingMode% 29) इसके लिए विधि। पहला पैरामीटर (स्केल) निर्दिष्ट करता है कि आप दशमलव बिंदु के बाद कितनी संख्या रखना चाहते हैं, और दूसरा पैरामीटर (राउंडिंगमोड) आपके इच्छित गोलिंग व्यवहार को निर्दिष्ट करता है। –

4

यह मनोरंजन के लिए नहीं है। असल में मुझे कुछ ऑनलाइन उदाहरण मिला, जिसमें MathContext का उपयोग बिगडिसीमल में संग्रहीत मात्रा/संख्याओं के दौर के लिए किया गया था।

उदाहरण के लिए,

हैं MathContextprecision = 2 और rounding mode = ROUND_HALF_EVEN

BigDecimal Number = 0.5294 के लिए कॉन्फ़िगर किया गया है, है 0,53

को गोल तो मैंने सोचा कि यह एक नई तकनीक है और के लिए इसका इस्तेमाल किया गोल उद्देश्य हालांकि यह दुःस्वप्न में बदल गया क्योंकि यह संख्या के मंथिसा भाग को भी गोल करना शुरू कर दिया। इतने पर

तो

उदाहरण के लिए,

Number = 1.52941.5

Number = 10.5294 को गोल है 10

Number = 101.5294 को गोल है 100

को गोल है .... और यह व्यवहार नहीं है मैं गोल करने के लिए उम्मीद की (सटीक = 2 ​​के रूप में)।

ऐसा लगता है कि कुछ तर्क होने के कारण मुझे लगता है कि यह पहले दो अंक (सटीक 2 के रूप में) लेता है और फिर 0 तक नंबर जोड़ता है। अगोलाकर राशि के रूप में ही बन अंकों की (101.5294 का उदाहरण चेकआउट ...)

+1

तो क्या आप इसके बजाय समाधान के लिए भी सुझाव दे सकते हैं? –

52

बिगडिसीमल के केवल आंशिक भाग को गोल करने के लिए, BigDecimal.setScale(int newScale, int roundingMode) विधि देखें।

उदा। दो अंक हों एक के लिए कृपया दशमलव बिंदु के तीन अंक के साथ एक नंबर बदलने के लिए, और ऊपर गोलाई:

BigDecimal original = new BigDecimal("1.235"); 
BigDecimal scaled = original.setScale(2, BigDecimal.ROUND_HALF_UP); 

इसी का परिणाम मूल्य 1.24 के साथ एक BigDecimal (ऊपर गोलाई शासन की वजह से)

+15

यह वही उत्तर है जो लोगों को निश्चित-दशमलव संख्याओं के साथ काम करने और दशमलव स्थानों की एक निश्चित संख्या को रखने में है। पता नहीं क्यों सूर्य ने यहां एक फ्लोटिंग-पॉइंट शैली 'परिशुद्धता' को घुमाया, लेकिन यही वह है जो मैथकॉन्टेक्स्ट है। –

9
है

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

MathContext MATH_CTX = new MathContext(3, RoundingMode.HALF_UP); 

इस कोड के लिए:

BigDecimal d1 = new BigDecimal(1234.4, MATH_CTX); 
System.out.println(d1); 

यह पूरी तरह से स्पष्ट है, कि अपने परिणाम 1.23E+3 है के रूप में लोगों के ऊपर कहा। पहले महत्वपूर्ण अंक 123 हैं ...

लेकिन क्या इस मामले में:

BigDecimal d2 = new BigDecimal(0.000000454770054, MATH_CTX); 
System.out.println(d2); 

अपना नंबर अल्पविराम के बाद 3 अंकों तक राउंड नहीं किया जाएगा - किसी के लिए यह सहज और बल देने के लिए लायक नहीं हो सकता है। इसके बजाय इसे पर पहले 3 महत्वपूर्ण अंक पर गोल किया जाएगा, जो इस मामले में "4 5 4" हैं। तो कोड के परिणाम 4.55E-7 में और 0.000 में नहीं, क्योंकि कोई उम्मीद कर सकता है।

इसी प्रकार के उदाहरण:

BigDecimal d3 = new BigDecimal(0.001000045477, MATH_CTX); 
System.out.println(d3); // 0.00100 

BigDecimal d4 = new BigDecimal(0.200000477, MATH_CTX); 
System.out.println(d4); // 0.200 

BigDecimal d5 = new BigDecimal(0.000000004, MATH_CTX); 
    System.out.println(d5); //4.00E-9 

मुझे आशा है कि यह स्पष्ट है, लेकिन प्रासंगिक उदाहरण मददगार होगा ...