development

ArithmeticException :“비 종료 소수점 확장;

big-blog 2020. 2. 14. 23:45
반응형

ArithmeticException :“비 종료 소수점 확장; 정확하게 표현할 수있는 소수 결과가 없습니다”


다음 코드가 아래에 표시된 예외를 발생시키는 이유는 무엇입니까?

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.

로부터 자바 8 문서 :

MathContext 객체에 정밀도 설정 0 (예 : MathContext.UNLIMITED)이 제공되면 MathContext 객체를 사용하지 않는 산술 메서드와 마찬가지로 산술 연산이 정확합니다. (이것은 5 이전 릴리스에서 지원 된 유일한 동작입니다.)

정확한 결과를 계산 한 결과, 정밀도 설정이 0 인 MathContext 객체의 반올림 모드 설정은 사용되지 않으므로 관련이 없습니다. 나누기의 경우 정확한 몫은 무한 길이의 십진수 확장을 가질 수 있습니다. 예를 들어 1을 3으로 나눈 값입니다.

몫에 끝나지 않는 10 진수 확장이 있고 정확한 결과를 반환하도록 연산이 지정된 경우 ArithmeticException이 발생합니다. 그렇지 않으면 다른 작업에서와 같이 정확한 분할 결과가 반환됩니다.

수정하려면 다음과 같이해야합니다 .

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

where 2 is scale and RoundingMode.HALF_UP is rounding mode

자세한 내용은 http://jaydeepm.wordpress.com/2009/06/04/bigdecimal-and-non-terminating-decimal-expansion-error/


정밀도와 반올림 모드를 지정하지 않기 때문입니다. BigDecimal은 10, 20, 5000 또는 무한 소수점 자리를 사용할 수 있으며 여전히 숫자를 정확하게 표현할 수는 없다고 불평합니다. 따라서 잘못된 BigDecimal을 제공하는 대신 사용자에게 윙윙 거리는 소리입니다.

그러나 RoundingMode와 정밀도를 제공하면 (예 : 1.333333333에서 무한대를 1.3333과 같은 것으로 변환 할 수 있지만 ... 프로그래머는 당신이 어떤 정밀도에 만족하는지 말할 필요가 있습니다 '.


넌 할 수있어

a.divide(b, MathContext.DECIMAL128)

32,64,128 중 원하는 비트 수를 선택할 수 있습니다.

이 링크를 확인하십시오 :

http://edelstein.pebbles.cs.cmu.edu/jadeite/main.php?api=java6&state=class&package=java.math&class=MathContext


이러한 문제를 해결하기 위해 아래 코드를 사용했습니다.

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

2는 정밀도입니다. 이제 문제가 해결되었습니다.


내 코드 줄이 다음과 같기 때문에 동일한 문제가 발생했습니다.

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

십진수 정밀도를 쓰지 않았기 때문에 이전 답변을 읽는 것으로 변경합니다.

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

4는 10 진법

AND 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/


결과를 반올림하는 문제는 나를위한 해결책은 다음과 같습니다.

divider.divide(dividend,RoundingMode.HALF_UP);

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 객체를 추가하고 정밀도 및 반올림 모드를 조정하십시오. 문제를 해결해야합니다


Bigdecimal이 손실되지 않았기 때문에, 예를 들어 1/3을 나누면 무한대로 10 진수가 반복됩니다. 0.33333333 ... 이론적으로 다시 곱하면 정확한 결과가 나타납니다. 그러나 무한대 숫자는 스택 오버 플로우를 생성하며이 경우 예외가 시작됩니다.

해결책 :

 try {
     result = n1.divide(n2);
 } catch (ArithmeticException e){
     Log.d("Error bigdecimal", e.toString());
     result = (n1.doubleValue() / n2.doubleValue());
 };

또는

n1.divide(n2,RoundingMode.HALF_UP);

이 경우 결과는 반올림으로 잘리지 않습니다.


프로그램은 십진수의 정밀도를 알지 못하므로 다음을 throw합니다.

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

참고 URL : https://stackoverflow.com/questions/4591206/arithmeticexception-non-terminating-decimal-expansion-no-exact-representable



반응형