programing

소수점 이하 두 자리까지 반올림하다

goodcopy 2022. 7. 24. 23:20
반응형

소수점 이하 두 자리까지 반올림하다

값이 다음과 같은 경우200.3456포맷은 다음과 같습니다.200.34.그렇다면200, 그러면 다음과 같이 됩니다.200.00.

여기에서는, 소수점 이하 2 자리수의 반올림을 실시하는 유틸리티가 있습니다.

예를 들어 다음과 같습니다.

round(200.3456, 2); // returns 200.35

오리지널 버전입니다.주의하세요.

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    long factor = (long) Math.pow(10, places);
    value = value * factor;
    long tmp = Math.round(value);
    return (double) tmp / factor;
}

이것은 소수점 이하가 매우 높은 코너 케이스(예: 소수점 이하)에서는 잘 분해되지 않습니다.round(1000.0d, 17)또는 큰 정수 부분(예:round(90080070060.1d, 9)). Sloin씨가 지적해 주셔서 감사합니다.

위 내용을 사용하여 몇 년 전부터 소수점 2자리 또는 3자리까지 반올림하고 있습니다(예를 들어 로깅을 위해 청소 시간을 초단위로 27.987654321987 -> 27.99).하지만 더 확실한 방법을 쉽게 구할 수 있고 더 깨끗한 코드도 있기 때문에 피하는 것이 가장 좋을 것 같습니다.

그래서 대신 이걸 쓰세요.

(Louis Wasserman답변과 Sean Owen의 답변에서 인용)

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    BigDecimal bd = BigDecimal.valueOf(value);
    bd = bd.setScale(places, RoundingMode.HALF_UP);
    return bd.doubleValue();
}

주의:HALF_UP반올림 모드 '학교에서 가르치는 수업'입니다.Bankers' Rounding다른 것이 필요하다고 생각되는 경우 RoundingMode 문서를 참조하십시오.

물론 필요에 따라 위의 내용을 한 줄로 인라인화할 수 있습니다.
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

그리고 모든 경우에

부동소수점 표현은 항상 다음을 사용하여float그리고.double정확하지 않습니다.예를 들어 다음 식을 생각해 보겠습니다.

999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001

정확하게는 Big Decimal을 사용합니다.그 사이에 String을 사용하는 컨스트럭터를 사용합니다.더블을 사용하는 것은 사용하지 마십시오.예를 들어 다음과 같이 실행해 보겠습니다.

System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));

이 주제에 대한 훌륭한 추가 정보:


숫자를 엄밀하게 반올림하는 대신(또는 숫자 이외에) 문자열 형식을 원하는 경우 다른 답변을 참조하십시오.

특히,round(200, 0)돌아온다200.0. "200.00"을 출력하려면 먼저 반올림한 후 출력 결과를 포맷해야 합니다(Jesper의 답변에 완벽하게 설명되어 있습니다).

인쇄를 원하시면double소수점 뒤에 두 자리 숫자가 있는 경우 다음과 같이 사용합니다.

double value = 200.3456;
System.out.printf("Value: %.2f", value);

를 「」로 는,String " " 를 사용합니다.String.format()같은 인수를 사용합니다.

String result = String.format("%.2f", value);

class를 합니다.DecimalFormat:

DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));

이게 더 쉬울 것 같아요.

double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");      
time = Double.valueOf(df.format(time));

System.out.println(time); // 200.35

형식뿐만 아니라 반올림도 실제로 수행된다는 점에 유의하십시오.

가장 쉬운 방법은 이런 속임수를 쓰는 것입니다.

double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;

val이 200.3456에서 시작하면 20034로 넘어갑니다.56은 20035로 반올림한 다음 나누면 200.34가 됩니다.

항상 반올림하고 싶다면 언제든지 int에 캐스팅하여 잘라낼 수 있습니다.

double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;

이 방법은 매우 큰 복식(양수 또는 음수)의 경우 오버플로가 발생할 수 있기 때문에 대부분의 경우에 사용할 수 있습니다.그러나 값이 적절한 범위 내에 있는 것을 알고 있는 경우에는 이 방법이 효과적입니다.

Apache 공통 계산을 사용하십시오.

Precision.round(10.4567, 2)
function Double round2(Double val) {
    return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}

toString()!!!

이는 Big Decimal이 이중의 정확한 바이너리 형식을 변환하기 때문입니다.

다음은 권장되는 다양한 방법과 실패 사례입니다.

// Always Good!
new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue() 

Double val = 260.775d; //EXPECTED 260.78
260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue()

Double val = 260.775d; //EXPECTED 260.78
260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d  

Double val = 256.025d; //EXPECTED 256.03d
256.02 - OOPS - new DecimalFormat("0.00").format(val) 
// By default use half even, works if you change mode to half_up 

Double val = 256.025d; //EXPECTED 256.03d
256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0;
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");      
System.out.println(df.format(value));

예를 들어 같은 더블을 원하지만 원하는 방식으로 반올림한 경우에는 Big Decimal을 사용할 수 있습니다.

new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);

반올림 두 자리일 경우.매우 단순하고 기본적으로 Decimal Format이 수행하는 표시 목적뿐만 아니라 변수를 업데이트합니다.

x = Math.floor(x * 100) / 100;

더블 라운딩은 보통 원하는 것이 아니다.대신 를 사용하여 원하는 형식으로 표현하십시오.

질문하신 대로 반올림도 피하고 싶은 것 같습니까?.반올림 format()은 Afaik를 의미합니까?
반올림하고 싶다면 200.3456은 2의 정밀도에 200.35가 되어야 하는데, 당신의 경우 첫 번째 2를 원하시면 나머지 2를 폐기하시겠습니까?

100을 곱한 후 다시 100으로 나누기 전에 int로 캐스트할 수 있습니다.

200.3456 * 100 = 20034.56;  
(int) 20034.56 = 20034;  
20034/100.0 = 200.34;

하지만 정말 큰 숫자가 경계에 가까워지면 문제가 생길 수 있습니다.이 경우엔 끈으로 변환해서 서브스트링을 하는 것도 그만큼 쉬울 거예요

value = (int)(value * 100 + 0.5) / 100.0;

언급URL : https://stackoverflow.com/questions/2808535/round-a-double-to-2-decimal-places

반응형