2014-04-14 2 views
-1

Java에서 BigDecimal을 8 자 (분리 기호 포함)로 형식화하고 반올림을 사용하고 싶습니다. 몇 가지 예 :BigDecimal 서식 지정

12345.6789 -> "12345.68" 
123  -> " 123.0" 
0.12345678 -> "0.123457" 
1.5  -> "  1.5" 
0.0045  -> " 0.0045" 
12   -> " 12.0" 

결과에는 8 자까지 입력 할 수있는 공백이 있어야합니다. 가장 쉬운 방법은 무엇입니까?

+0

작동하지 않는 것을 포함 할 수 있습니까? –

답변

0

저는 이것이 최선의 방법은 아니지만 한 가지 방법 일 것이라고 확신합니다.

기간 이전에 숫자가 6 자리 이상이거나 일반적으로 width - 2 자 이상인 경우 .0의 형식은 더 이상 작동하지 않습니다.

String.format()은 반올림 방법으로 반올림을 사용하므로 출력을 8 자로 가져 오는 첫 번째 단계로 사용할 수 있습니다.

BigDecimal b = new BigDecimal(0.0045); 
String format = "%8f"; 
String str = String.format(format, b); 

출력 : 기본적 String.format()으로

12345.678900 
123.000000 
0.123457 
1.500000 
0.004500 
12.000000 
123456.000000 

BigDecimal 6의 정밀도를 사용합니다. 사용자 정의 정밀도를 얻으려면 기간 전에 얼마나 많은 자릿수인지 확인하고 총 너비에서이 수를 빼십시오 (기간 자체는 + 1). (number % radix) == number가 기수를 신청하는 경우

width - digits - 1 

는 자리의 수를 단순히 확인하실 수 있습니다 얻으려면 = 10, 100, 1000, ... 즉시 당신이 자리의 수를 알 맞는있다.

public static int digitsBeforePeriod(BigDecimal b) { 
    int number = b.intValue(); 
    int radix = 10; 
    int digits = 1; 
    while((number % radix) != number) { 
     radix *= 10; 
     ++digits; 
    } 
    return digits; 
} 

그래서 다음 단계는 형식을 수정하는 것입니다 :

BigDecimal b = new BigDecimal(0.0045); 
int digits = digitsBeforePeriod(b); 
String format = "%8." + (8 - digits - 1) + "f"; 
String str = String.format(format, b); 

출력 :

12345.68 
123.0000 
0.123457 
1.500000 
0.004500 
12.00000 
123456.0 

는 여전히 0이 많이있다,하지만 적어도 라운딩 지금 맞습니다. 이제 숫자가 정수로 반올림되는 경우 접미어 .0을 사용하여 인쇄 할 것을 지정합니다. 그렇지 않은 경우 그렇지 않습니다.

영리한 형식이있을 수도 있지만 더 이상 생각하지 못했습니다. 이 작업을 수행하는 순진 방법은 간단하다 :

while(str.endsWith("0") && !str.endsWith(".0")) { 
    str = str.substring(0, str.length()-1); 
} 

이것은 하나 전혀 0에 종료 또는 .0로 종료하지 않을 때까지 문자열의 마지막 문자를 제거합니다.

이제 숫자가 올바른 형식을해야하지만 제대로 정렬되지 않습니다

12345.68 
123.0 
0.123457 
1.5 
0.0045 
12.0 
123456.0 

은 다시 String.format()를 사용을 맞 춥니 다.

str = String.format("%" + width + "s", str); 

출력 :이 다음과 같은 맥락에서

12345.68 
    123.0 
0.123457 
    1.5 
    0.0045 
    12.0 
123456.0 

.수표를 포함 시켰는지 또는 그 수를 그런 식으로 서식을 지정할 수 없는지 유의하십시오. 그렇지 않으면 유효하지 않습니다. 물론 번호를 인쇄 할 수도 있습니다. 단지 그 형식의 한계를 보여주고 싶었습니다.

public static String trimToWidth(BigDecimal b, int width) { 
    String str = "Invalid"; 
    int digits = digitsBeforePeriod(b); 

    // -2 for period and 0 
    if(digits <= width - 2) { 
     // use width and (width - digits - 1) as precision (-1 for period) 
     String format = "%" + width + "." + (width - digits - 1) + "f"; 
     // rounds half-up 
     str = String.format(format, b); 

     // trim trailing 0s, unless it's .0 
     while(str.endsWith("0") && !str.endsWith(".0")) { 
      str = str.substring(0, str.length()-1); 
     } 
    } 

    // add spaces in front 
    str = String.format("%" + width + "s", str); 

    return str; 
} 

public static int digitsBeforePeriod(BigDecimal b) { 
    int number = b.intValue(); 
    int radix = 10; 
    int d = 1; 
    while((number % radix) != number) { 
     radix *= 10; 
     ++d; 
    } 
    return d; 
} 

public static void main(String[] args) { 
    double[] values = new double[] { 
      12345.6789, 123, 0.12345678, 
      1.5, 0.0045, 12, 123456, 1234567 
    }; 

    BigDecimal[] bigs = new BigDecimal[values.length]; 

    for(int i = 0; i < bigs.length; ++i) { 
     bigs[i] = new BigDecimal(values[i]); 
     System.out.println(trimToWidth(bigs[i], 8)); 
    } 

}