programing

Java: Precision을 이중으로 설정하는 방법

yoursource 2022. 9. 16. 21:11
반응형

Java: Precision을 이중으로 설정하는 방법

최근 숫자를 사용하고 있었는데, 데이터베이스에 저장되어 있는 값에 따라 2배값의 정밀도를 6자리 또는 4자리로 설정하고 싶은 상황이 있었습니다.

예를 들어 데이터베이스에서 정밀도가 4자리 숫자로 설정되어 있는 경우 출력은 다음과 같이 표시되어야 합니다.

10.0000.

로 시도했다.DecimalFormat스트링을 사용하여##.####하지만 매번 기호를 사용하는 것은 짜증난다.

다음과 같은 더 나은 방법이 있습니까?

Double value = 10.0;
value.setPrecision(4);

이 목적을 위해 Big Decimal을 시도할 수 있습니다.

Double toBeTruncated = new Double("3.5789055");

Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
    .setScale(3, RoundingMode.HALF_UP)
    .doubleValue();

부동소수점 값에는 십진수가 없기 때문에 두 자리(또는 두 자리)의 정밀도를 지정된 십진수로 설정할 수 없습니다.2진수입니다.

다음 중 하나를 사용하여 소수 기수로 변환해야 합니다.BigDecimal또는DecimalFormat나중에 값을 사용하여 수행할 작업에 따라 달라집니다.

불가피한 *100/100 답변에 대한 반박은 이 질문에 대한 답변도 참조하십시오.

간단한 방법은 다음과 같습니다.

String formato = String.format("%.2f");

정밀도를 2자리로 설정합니다.

인쇄만 하는 경우는, 다음과 같이 사용합니다.

System.out.printf("%.2f",123.234);

이중 값의 정밀도를 설정하는 방법DecimalFormat좋은 기술입니다.이 클래스 가져오기를 사용하려면java.text.DecimalFormat예를 들어 오브젝트를 만듭니다.

double no=12.786;
DecimalFormat dec = new DecimalFormat("#0.00");
System.out.println(dec.format(no));

그래서 소수점 뒤에 두 자리 숫자가 인쇄되고 12.79가 인쇄됩니다.

이 방법은 효과가 있었습니다.

public static void main(String[] s) {
        Double d = Math.PI;
        d = Double.parseDouble(String.format("%.3f", d));  // can be required precision
        System.out.println(d);
    }

여기 두 가지 주의사항을 가지고 결과를 얻는 효율적인 방법이 있습니다.

  1. 정밀도를 '최대' N자리로 제한합니다(N자리로 고정되지 않음).
  2. 숫자를 반올림합니다(가장 가까운 값으로 반올림하지 않음).

샘플 테스트 케이스는 이쪽을 참조해 주세요.

123.12345678 ==> 123.123
1.230000 ==> 1.23
1.1 ==> 1.1
1 ==> 1.0
0.000 ==> 0.0
0.00 ==> 0.0
0.4 ==> 0.4
0 ==> 0.0
1.4999 ==> 1.499
1.4995 ==> 1.499
1.4994 ==> 1.499

여기 암호가 있습니다.위의 두 가지 경고는 매우 쉽게 해결할 수 있지만 정확성보다 속도가 중요하기 때문에 여기에 남겨두었습니다.다음과 같은 문자열 조작System.out.printf("%.2f",123.234);수학적 연산에 비해 계산 비용이 많이 듭니다.테스트에서는 아래 코드(sysout 미포함)는 String 조작에 비해 1/30의 시간이 소요되었습니다.

public double limitPrecision(String dblAsString, int maxDigitsAfterDecimal) {
    int multiplier = (int) Math.pow(10, maxDigitsAfterDecimal);
    double truncated = (double) ((long) ((Double.parseDouble(dblAsString)) * multiplier)) / multiplier;
    System.out.println(dblAsString + " ==> " + truncated);
    return truncated;
}

의 정밀도double그리고.float는 그 크기와 IEEE 부동소수점 타입의 실장 방법에 의해 고정됩니다.

한편, 출력의 10 진수는 포맷의 문제입니다.같은 상수를 반복해서 입력하는 것은 좋지 않습니다.대신 문자열 상수를 선언하고 해당 기호 표현을 사용해야 합니다.

private static final String DBL_FMT = "##.####";

기호 표현을 사용하면 코드를 검색하지 않고도 상수가 사용되는 모든 위치의 정밀도를 변경할 수 있습니다.

@EJP로 확대하면, 더블을 취급할 때의 「정밀」의 개념은 매우 곤란합니다.https://stackoverflow.com/a/3730040/390153에서 설명한 바와 같이 정밀도에 관계없이 0.1을 배수로 표현할 수 없습니다.또한 같은 이유로 베이스 10의 1/3을 한정된 정밀도로 표현할 수 없습니다.

해결하려고 하는 문제를 고려하여 다음 사항을 고려해야 합니다.

a) 애초에 더블을 사용해야 합니까?정밀도가 관련 개념이라면 더블을 사용하는 것은 실수일 수 있습니다.

b) 더블이 적절하다면 정밀도란 무엇인가?디스플레이에 대해서만 언급하는 경우 로직을 디스플레이 기능으로 감싸면 한 곳에서만 처리할 수 있습니다. 즉, DRY 원칙을 적용합니다.

BigDecimal value = new BigDecimal(10.0000);
value.setScale(4);
public static String setPrecision(String number, int decimal) {
    double nbr = Double.valueOf(number);
    int integer_Part = (int) nbr;
    double float_Part = nbr - integer_Part;
    int floating_point = (int) (Math.pow(10, decimal) * float_Part);
    String final_nbr = String.valueOf(integer_Part) + "." + String.valueOf(floating_point);
    return final_nbr;
}

이 방법은 이중 값을 사전화하는 데 도움이 될 수 있습니다.

double truncate(double number)
    {
        int integerPart = (int) number;
        double fractionalPart = number - integerPart;
        fractionalPart *= 100;  //It is for upto two decimal values after point.
                                //You can increase the zeros to fulfill your needs.
        int fractPart = (int) fractionalPart;
        fractionalPart = (double) (integerPart) + (double) (fractPart)/100;
        return fractionalPart;
    }

이 방법을 사용하면 정밀도 레벨을 설정할 수 있습니다.

double truncate(double number, int precision)
{
    double prec = Math.pow(10, precision);
    int integerPart = (int) number;
    double fractionalPart = number - integerPart;
    fractionalPart *= prec;
    int fractPart = (int) fractionalPart;
    fractionalPart = (double) (integerPart) + (double) (fractPart)/prec;
    return fractionalPart;
}

언급URL : https://stackoverflow.com/questions/14845937/java-how-to-set-precision-for-double-value

반응형