IT TIP

double을 BigDecimal로 변환하고 BigDecimal 정밀도 설정

itqueen 2020. 12. 26. 16:24
반응형

double을 BigDecimal로 변환하고 BigDecimal 정밀도 설정


Java에서는 이중 값을 가져 와서 a로 변환 BigDecimal하고 문자열 값을 특정 정밀도로 인쇄하고 싶습니다 .

import java.math.BigDecimal;
public class Main {
    public static void main(String[] args) {
        double d=-.00012;
        System.out.println(d+""); //This prints -1.2E-4

        double c=47.48000;
        BigDecimal b = new BigDecimal(c);
        System.out.println(b.toString()); 
        //This prints 47.47999999999999687361196265555918216705322265625 
    }
}

이 거대한 것을 인쇄합니다.

47.47999999999999687361196265555918216705322265625

그리고 아닙니다

47.48

내가 BigDecimal변환 을하는 이유 는 때때로 double 값이 많은 소수 자리를 포함 할 것이고 (즉 -.000012) double을 String으로 변환 할 때 과학적 표기법을 생성하기 때문 -1.2E-4입니다. 비 과학적 표기법으로 문자열 값을 저장하고 싶습니다.

BigDecimal은 항상 "47.48"과 같은 두 단위의 정밀도를 갖기를 원합니다. BigDecimal이 문자열 변환의 정밀도를 제한 할 수 있습니까?


다른 MathContext 를 사용하면 47.48000이 인쇄됩니다 .

BigDecimal b = new BigDecimal(d, MathContext.DECIMAL64);

필요한 컨텍스트를 선택하기 만하면됩니다.


이러한 동작의 이유는 인쇄되는 문자열이 정확한 값이기 때문입니다. 예상 한 값은 아닐 수 있지만 메모리에 저장된 실제 값은 부동 소수점 표현의 제한 일뿐입니다.

javadoc에 따르면이 제한 사항을 고려하지 않으면 BigDecimal (double val) 생성자 동작이 예기치 않게 발생할 수 있습니다.

이 생성자의 결과는 다소 예측할 수 없습니다. Java에서 new BigDecimal (0.1)을 작성하면 정확히 0.1 (스케일되지 않은 값 1, 스케일 1) 인 BigDecimal이 생성되지만 실제로는 0.1000000000000000055511151231257827021181583404541015625와 같습니다. 0.1은 정확히 double로 표현할 수 없기 때문입니다 (또는 유한 길이의 이진 분수로 표현할 수 없습니다). 따라서 생성자에 전달되는 값은 외관에도 불구하고 정확히 0.1과 동일하지 않습니다.

따라서 귀하의 경우에는

double val = 77.48;
new BigDecimal(val);

사용하다

BigDecimal.valueOf(val);

BigDecimal.valueOf에서 반환되는 값은 Double.toString(double).


String.format("%f", d)십진수 표기법으로 double을 인쇄하는 을 시도하고 싶습니다 . 전혀 사용하지 마십시오 BigDecimal.

정밀도 문제에 대해서 : 먼저 저장하는 47.48double c, 새로운를 만드는 BigDecimal것과 double. 정밀도 손실은 c. 당신은 할 수 있습니다

BigDecimal b = new BigDecimal("47.48")

정밀도 손실을 방지합니다.


의 실제 정확한 값을 인쇄합니다 double.

Double.toString()doubles를 Strings 로 변환 하는은 입력의 정확한 십진수 값을 인쇄 하지 않습니다.x 이 두 배 값이면 인쇄 한 값에 x가장 가까운 숫자를 정확히 double인쇄합니다.

요점은 정확히 47.48 과 같은 것이 없다는double 것입니다. 저장 값을 소수가 아닌 이진 분수 로 두 배로 지정 하므로 정확한 소수 값을 저장할 수 없습니다. (그게 BigDecimal목적입니다!)


왜 안 되는가 :

b = b.setScale(2, RoundingMode.HALF_UP);

String.format 구문은 double과 BigDecimal을 정밀도에 관계없이 문자열로 변환하는 데 도움이됩니다.

이 자바 코드 :

double dennis = 0.00000008880000d;
System.out.println(dennis);
System.out.println(String.format("%.7f", dennis));
System.out.println(String.format("%.9f", new BigDecimal(dennis)));
System.out.println(String.format("%.19f", new BigDecimal(dennis)));

인쇄물:

8.88E-8
0.0000001
0.000000089
0.0000000888000000000

BigDecimal b = new BigDecimal(c).setScale(2,BigDecimal.ROUND_HALF_UP);

Java 9에서 다음은 더 이상 사용되지 않습니다.

BigDecimal.valueOf(d). setScale (2, BigDecimal. ROUND_HALF_UP );

대신 다음을 사용하십시오.

BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);

예:

    double d = 47.48111;

    System.out.println(BigDecimal.valueOf(d)); //Prints: 47.48111

    BigDecimal bigDecimal = BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);
    System.out.println(bigDecimal); //Prints: 47.48

참조 URL : https://stackoverflow.com/questions/12395281/convert-double-to-bigdecimal-and-set-bigdecimal-precision

반응형