[java] 불필요한 십진수 0없이 부동 숫자를 String으로 멋지게 포맷하는 방법은 무엇입니까?

64 비트 double은 정수 +/- 2 53을 정확하게 나타낼 수 있습니다

이 사실을 감안할 때 가장 큰 정수는 부호없는 32 비트이므로 모든 유형의 단일 유형으로 이중 유형을 사용하기로 선택했습니다.

그러나 이제 이러한 의사 정수를 인쇄해야하지만 문제는 실제 복식과 혼합되어 있다는 것입니다.

Java 에서이 복식을 어떻게 잘 인쇄합니까?

나는 String.format("%f", value)작은 값에 대해 많은 후행 0을 얻는 것을 제외하고는 가까운 시도했습니다 .

다음은 출력 예입니다. %f

232.00000000
0.18000000000
1237875192.0
4.5800000000
0.00000000
1.23450000

내가 원하는 것은 :

232
0.18
1237875192
4.58
0
1.2345

물론 제로를 트리밍하는 함수를 작성할 수는 있지만 문자열 조작으로 인해 많은 성능 손실이 발생합니다. 다른 형식 코드로 더 잘 할 수 있습니까?

편집하다

Tom E.와 Jeremy S.의 답변은 모두 소수점 이하 두 자리로 임의로 반올림되므로 받아 들일 수 없습니다. 답변하기 전에 문제를 이해하십시오.

편집 2

참고 사항 String.format(format, args...)이다 로케일 종속은 (아래 답변을 참조).



답변

아이디어가 정수인 것처럼 double로 저장된 정수를 인쇄하는 경우 필요한 최소 정밀도로 double을 인쇄하십시오.

public static String fmt(double d)
{
    if(d == (long) d)
        return String.format("%d",(long)d);
    else
        return String.format("%s",d);
}

생산 :

232
0.18
1237875192
4.58
0
1.2345

그리고 문자열 조작에 의존하지 않습니다.


답변

new DecimalFormat("#.##").format(1.199); //"1.2"

의견에서 지적했듯이 이것은 원래 질문에 대한 정답이 아닙니다.
즉, 불필요한 후행 0없이 숫자를 형식화하는 매우 유용한 방법입니다.


답변

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


답변

한마디로 :

후행 0과 로케일 문제를 제거하려면 다음을 사용해야합니다.

double myValue = 0.00000021d;

DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); //340 = DecimalFormat.DOUBLE_FRACTION_DIGITS

System.out.println(df.format(myValue)); //output: 0.00000021

설명:

다른 답변이 나에게 적합하지 않은 이유 :

  • Double.toString()또는 System.out.println또는 FloatingDecimal.toJavaFormatString이중 10 개 미만인 경우 ^ -3 과학적 표기법을 사용하거나보다 큰 10 ^ 7 동등

    double myValue = 0.00000021d;
    String.format("%s", myvalue); //output: 2.1E-7
  • 을 사용 %f하면 기본 10 진수 정밀도는 6이며, 그렇지 않으면 하드 코딩 할 수 있지만 소수가 적 으면 추가 0이 추가됩니다. 예 :

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); //output: 0.000000210000
  • 십진 정밀도 를 사용 setMaximumFractionDigits(0);하거나 %.0f제거 하여 정수 / 길이에는 좋지만 두 배에는 적합하지 않습니다.

    double myValue = 0.00000021d;
    System.out.println(String.format("%.0f", myvalue)); //output: 0
    DecimalFormat df = new DecimalFormat("0");
    System.out.println(df.format(myValue)); //output: 0
  • DecimalFormat을 사용하면 로컬에 따라 다릅니다. 프랑스어 로케일에서 소수점 구분 기호는 점이 아닌 쉼표입니다.

    double myValue = 0.00000021d;
    DecimalFormat df = new DecimalFormat("0");
    df.setMaximumFractionDigits(340);
    System.out.println(df.format(myvalue));//output: 0,00000021

    ENGLISH 로케일을 사용하면 프로그램이 실행되는 곳에서 소수점 구분 기호를 얻을 수 있습니다

왜 340을 사용 setMaximumFractionDigits합니까?

두 가지 이유 :

  • setMaximumFractionDigits정수를 허용하지만 구현에 허용되는 최대 자릿수는 DecimalFormat.DOUBLE_FRACTION_DIGITS340입니다.
  • Double.MIN_VALUE = 4.9E-324 따라서 340 자리 숫자로 배정도의 정밀도를 반올림하지 않아야합니다.

답변

왜 안되 겠어요 :

if (d % 1.0 != 0)
    return String.format("%s", d);
else
    return String.format("%.0f",d);

이것은 Double에서 지원하는 극단적 인 값에서 작동합니다. 수율 :

0.12
12
12.144252
0


답변

내 컴퓨터에서 다음 기능은 JasonD의 답변 에서 제공하는 기능보다 약 7 배 빠릅니다 String.format.

public static String prettyPrint(double d) {
  int i = (int) d;
  return d == i ? String.valueOf(i) : String.valueOf(d);
}


답변

내 2 센트 :

if(n % 1 == 0) {
    return String.format(Locale.US, "%.0f", n));
} else {
    return String.format(Locale.US, "%.1f", n));
}