source

더블을 Big Decimal로 변환하고 Big Decimal Precision을 설정합니다.

itover 2022. 12. 31. 16:37
반응형

더블을 Big Decimal로 변환하고 Big Decimal Precision을 설정합니다.

자바에서는 이중값을 취해서 변환하고 싶다.BigDecimalString 값을 일정한 정밀도로 출력합니다.

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변환은 때때로 두 배 값에 소수 자릿수가 많이 포함되기도 합니다(즉,-.000012) 및 더블을 문자열로 변환하면 과학적 표기가 생성됩니다.-1.2E-4. String 값을 비과학적 표기법으로 저장합니다.

Big Decimal은 항상 두 개의 정밀도를 가지고 싶습니다. "47.48"입니다.Big Decimal은 문자열로의 변환 정밀도를 제한할 수 있습니까?

이러한 동작의 이유는 출력되는 문자열이 정확한 값(예상했던 값은 아닐 수 있지만 메모리에 저장된 실제 값)이기 때문입니다.이것은 부동소수점 표현의 제한에 불과합니다.

javadoc에 따르면 BigDecimal(double val) 컨스트럭터의 동작은 이 제한을 고려하지 않으면 예측할 수 없습니다.

이 생성자의 결과는 다소 예측할 수 없습니다.Java에서 새로운 BigDecimal(0.1)을 쓸 경우 0.1(스케일1의 스케일1의 비스케일값)과 정확히 같은 BigDecimal이 생성된다고 생각할 수 있지만 실제로는 0.100000000005511151231257821188340415625와 동일합니다.이는 0.1을 정확히 2배로 나타낼 수 없기 때문입니다(또는 그 문제의 경우 유한 길이의 2진수로 표현).따라서 컨스트럭터에 전달되는 값은 외관상으로는 0.1과 완전히 동일하지 않습니다.

그래서 당신의 경우,

double val = 77.48;
new BigDecimal(val);

사용하다

BigDecimal.valueOf(val);

BigDecimal.valueOf에 의해 반환되는 값은 호출된 값과 동일합니다.Double.toString(double).

다른 MathContext를 사용하면 47.48000 이 출력됩니다.

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

필요한 콘텍스트를 선택해 주세요.

해보고 싶어?String.format("%f", d)10진 표기로 더블을 인쇄합니다.사용하지 않다BigDecimal조금도.

정밀도 문제에 대해서:먼저 저장하려고 합니다.47.48에서double c, 그 후 새로운 것을 만듭니다.BigDecimal그것으로부터double...정밀성의 손실은 다음 항목에 할당하는 데 있습니다.c할 수 있다

BigDecimal b = new BigDecimal("47.48")

정확성을 잃지 않기 위해서요.

왜 안 되는 이유:

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

실제 정확한 값을 출력하는 것입니다.double.

Double.toString()double ~ ~까지Strings는 입력의 정확한 10진수 값을 출력하지 않습니다.x은 두입니다. 이 은 ''가 될 만큼 됩니다.그것은 정확하게 충분한 자릿수를 출력합니다.x double인쇄된 값까지.

요점은 정확히 47.48과 같은 것은 없다는 것이다.두 배수는 값을 소수점이 아닌 이진수로 저장하므로 정확한 소수점 값을 저장할 수 없습니다.(그렇습니다.BigDecimal★★★★★★★★★★★★★★★★★★」

스트링format 구문을 사용하면 더블 및 BigDecimals를 어떤 정밀도의 문자열로 변환할 수 있습니다.

다음 자바 코드:

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. 반올림업. );

대신 다음을 사용합니다.

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

반응형