Programing

Java : 이중 값에 대한 정밀도를 설정하는 방법은 무엇입니까?

crosscheck 2020. 9. 20. 08:48
반응형

Java : 이중 값에 대한 정밀도를 설정하는 방법은 무엇입니까? [복제]


이 질문에 이미 답변이 있습니다.

최근에 숫자 작업을했는데 데이터베이스에 저장된 값에 따라 이중 값의 정밀도를 6 자리 또는 4 자리로 설정하고 싶은 상황이있었습니다.

예를 들어, 데이터베이스에서 정밀도가 4 자리로 설정된 경우 출력은 다음과 같아야합니다.

10.0000.

나는 DecimalFormat문자열을 사용해 보았지만 ##.####매번 기호를 사용하는 것은 성가신 일입니다.

더 나은 접근 방법이 있습니까? 다음과 같이 말하십시오.

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

부동 소수점 값에는 10 진수가 없기 때문에 double (또는 Double)의 정밀도를 지정된 10 진수 숫자로 설정할 수 없습니다. 이진수가 있습니다.

당신은을 통해 중, 진수 기수로 전환해야합니다 BigDecimal또는 DecimalFormat나중에 값으로 수행 할 작업에 따라.

피할 수없는 * 100 / 100 답변에 대한 반박은 이 질문에 대한 나의 답변을 참조하십시오 .


이 목적으로 BigDecimal사용해 볼 수 있습니다.

Double toBeTruncated = new Double("3.5789055");

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

이것은 쉽게 할 수있는 방법입니다.

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

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

인쇄 만하려면 다음과 같이 사용하십시오.

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

double 값에 대한 정밀도를 설정하는 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없이)는 문자열 조작에 비해 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 부동 소수점 유형 이 구현 되는 방식으로 고정됩니다 .

반면 출력의 소수 자릿수는 형식화의 문제입니다. 같은 상수를 반복해서 입력하는 것은 나쁜 생각이라는 것이 맞습니다. 대신 문자열 상수를 선언하고 기호 표현을 사용해야합니다.

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

Using a symbolic representation would let you change precision in all places the constant is used without searching through your code.


BigDecimal value = new BigDecimal(10.0000);
value.setScale(4);

To expand on @EJP, the concept of 'precision' when dealing with doubles is extremely fraught. As discussed in https://stackoverflow.com/a/3730040/390153 you can't even represent 0.1 as a double regardless of the precision, for the same reason you can't represent 1/3 in base 10 with finite precision.

You need to consider the problem you are trying to solve, and consider:

a) Should I be using doubles in the first place; if precision is a relevant concept, then using doubles may well be a mistake.

b) If doubles are appropriate, what do I mean by precision? If you are only talking about display, wrap the logic in a display function and you will only need to deal with it in one place; ie. apply the DRY principle.


Maybe this method would help you for precising double values.

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;
    }

This method will allow to set the precision level.

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;
}

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;
}

I saw the answer at top:

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

which I think is not the perfect answer, because the answer will change when you call doubleValue() in many cases.

Example: output of BigDecimal.valueOf(toBeTruncated).setScale(3, RoundingMode.HALF_UP) is 12.500,

then after .doubleValue(), the output will be 12.5 i.e. precision is lost.

Solution: either use BigDecimal type without .doubleValue() method to display, or use string formatting after the final answer.

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

반응형