अंकगणित अपवाद: "गैर-समाप्ति दशमलव विस्तार; कोई सटीक प्रतिनिधित्व योग्य दशमलव परिणाम "


507

निम्न कोड नीचे दिखाए गए अपवाद को क्यों बढ़ाता है?

BigDecimal a = new BigDecimal("1.6");
BigDecimal b = new BigDecimal("9.2");
a.divide(b) // results in the following exception.

अपवाद:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

जवाबों:


841

से जावा 11 BigDecimalडॉक्स :

जब किसी MathContextऑब्जेक्ट को 0 की सटीक सेटिंग (उदाहरण के लिए MathContext.UNLIMITED) के साथ आपूर्ति की जाती है , तो अंकगणितीय संचालन सटीक होते हैं, जैसा कि अंकगणितीय तरीके हैं जो कोई MathContextऑब्जेक्ट नहीं लेते हैं । (यह एकमात्र ऐसा व्यवहार है जिसे 5. से पहले रिलीज में समर्थन किया गया था)

सटीक परिणाम की गणना के एक कोरोलरी के रूप में, MathContext0 की सटीक सेटिंग के साथ किसी ऑब्जेक्ट की राउंडिंग मोड सेटिंग का उपयोग नहीं किया जाता है और इस प्रकार अप्रासंगिक हो जाता है। विभाजन के मामले में, सटीक भागफल में एक अनंत लंबा दशमलव विस्तार हो सकता है; उदाहरण के लिए, 1 3 से विभाजित।

यदि भागफल में एक गैर-दशमलव दशमलव विस्तार है और एक सटीक परिणाम वापस करने के लिए ऑपरेशन निर्दिष्ट है, तो एक ArithmeticExceptionफेंक दिया गया है। अन्यथा, विभाजन का सटीक परिणाम वापस आ जाता है, जैसा कि अन्य संचालन के लिए किया जाता है।

ठीक करने के लिए, आपको ऐसा कुछ करने की आवश्यकता है :

a.divide(b, 2, RoundingMode.HALF_UP)

जहां 2 स्केल और राउंडिंग मोड है। HALF_UP राउंडिंग मोड है

अधिक जानकारी के लिए इस ब्लॉग पोस्ट को देखें ।


3
यह जैस्पर त्रुटि के लिए भी काम करता है धन्यवाद समुदाय।
jaspersoft.com/questions/528968/…

27
2 नहीं है precision; यह है scale। कृपया docs.oracle.com/javase/7/docs/api/java/math/…
John Manko

(न्यू बिगडेसीमल (100))। डिवाइड (नया बिगडेसिमल (0.90), 2, राउंडिंगमोड.एचएएलएफ_यूपी)
उदा।

@AnandVarkeyPhilips इसका पैमाना है। जावदोक को देखें । संपादन अस्वीकार किया गया।
लोरने की मार्क्विस

@ user207421, मैंने गलती से इसे संपादित किया और पुन: प्रयोग करने की कोशिश की .. लेकिन एक संपादन को हटाने के लिए पर्याप्त अंक नहीं थे .... meta.stackexchange.com/questions/80933/…
आनंद

76

क्योंकि आप एक सटीक और एक गोलाई-मोड निर्दिष्ट नहीं कर रहे हैं। BigDecimal शिकायत कर रहा है कि यह 10, 20, 5000 या अनंत दशमलव स्थानों का उपयोग कर सकता है, और यह अभी भी आपको संख्या का सटीक प्रतिनिधित्व नहीं दे पाएगा। तो इसके बजाय आप एक गलत BigDecimal देने के लिए, यह सिर्फ आप पर निर्भर करता है।

हालाँकि, यदि आप एक राउंडिंगमोड और एक परिशुद्धता की आपूर्ति करते हैं, तो यह कन्वर्ट करने में सक्षम होगा (उदाहरण के लिए। 1.333333333-to-infinity 1.3333 जैसी किसी चीज़ के लिए ... लेकिन प्रोग्रामर के रूप में आपको यह बताने की आवश्यकता है कि आप किस सटीकता से खुश हैं। '।



13

इस तरह के एक मुद्दे को ठीक करने के लिए मैंने नीचे दिए गए कोड का उपयोग किया है

a.divide(b, 2, RoundingMode.HALF_EVEN)

2 सटीक है। अब समस्या का समाधान हो गया था।


3
कोड के अलावा, कुछ स्पष्टीकरण प्रदान किया जाना चाहिए।
मार्टिन सेरानो

11
2 नहीं है precision; यह है scale। कृपया docs.oracle.com/javase/7/docs/api/java/math/…
John Manko

3
वित्तीय अनुप्रयोगों के लिए RoundingMode.HALF_EVEN की सिफारिश की जाती है। यह वह है जो बैंकिंग में उपयोग किया जाता है
ACV

उन लोगों के लिए, जो जॉन मेन्कोस की सटीकता पर टिप्पणी से भ्रमित हैं, कृपया इस उत्तर को देखें stackoverflow.com/questions/4591206/…
Stimpson Cat

5

मुझे भी यही समस्या थी, क्योंकि मेरी लाइन ऑफ कोड थी:

txtTotalInvoice.setText(var1.divide(var2).doubleValue() + "");

मैं इसका उत्तर बदल देता हूं, पिछले उत्तर को पढ़ना, क्योंकि मैं दशमलव सटीक नहीं लिख रहा था:

txtTotalInvoice.setText(var1.divide(var2,4, RoundingMode.HALF_UP).doubleValue() + "");

4 दशमलव दशमलव है

और RoundingMode Enum स्थिरांक हैं, आप इनमें से कोई भी चुन सकते हैं UP, DOWN, CEILING, FLOOR, HALF_DOWN, HALF_EVEN, HALF_UP

इस मामले में HALF_UP, का यह परिणाम होगा:

2.4 = 2   
2.5 = 3   
2.7 = 3

आप RoundingModeयहाँ जानकारी देख सकते हैं: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/


4 पैमाना है, परिशुद्धता नहीं।
मार्किस


1

BigDecimal का उत्तर ArithmeticException फेंकता है

public static void main(String[] args) {
        int age = 30;
        BigDecimal retireMentFund = new BigDecimal("10000.00");
        retireMentFund.setScale(2,BigDecimal.ROUND_HALF_UP);
        BigDecimal yearsInRetirement = new BigDecimal("20.00");
        String name = " Dennis";
        for ( int i = age; i <=65; i++){
            recalculate(retireMentFund,new BigDecimal("0.10"));
        }
        BigDecimal monthlyPension =   retireMentFund.divide(
                yearsInRetirement.divide(new BigDecimal("12"), new MathContext(2, RoundingMode.CEILING)), new MathContext(2, RoundingMode.CEILING));      
        System.out.println(name+ " will have £" + monthlyPension +" per month for retirement");
    }
public static void recalculate (BigDecimal fundAmount, BigDecimal rate){
        fundAmount.multiply(rate.add(new BigDecimal("1.00")));
    }

अपने डिवाइड विधि कॉल में MathContext ऑब्जेक्ट जोड़ें और सटीक और गोलाई मोड समायोजित करें। इससे आपकी समस्या ठीक होनी चाहिए


0

आपके प्रोग्राम को यह पता नहीं है कि दशमलव संख्याओं का उपयोग करने के लिए क्या सटीक है, इसलिए यह फेंकता है:

java.lang.ArithmeticException: Non-terminating decimal expansion

बायपास अपवाद का समाधान:

MathContext precision = new MathContext(int setPrecisionYouWant); // example 2
BigDecimal a = new BigDecimal("1.6",precision);
BigDecimal b = new BigDecimal("9.2",precision);
a.divide(b) // result = 0.17
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.