IT이야기

불필요한 소수점 0 없이 문자열에 부동소수 형식을 적절하게 지정하는 방법

cyworld 2022. 6. 15. 20:57
반응형

불필요한 소수점 0 없이 문자열에 부동소수 형식을 적절하게 지정하는 방법

64비트 더블은 정수 +/- 2를53 정확하게 나타낼 수 있습니다.

이 사실을 감안하여 모든 유형의 단일 유형으로 이중 유형을 선택합니다. 가장 큰 정수는 부호 없는 32비트 숫자이기 때문입니다.

하지만 이제 이 의사 정수를 인쇄해야 하는데 문제는 이것들도 실제 두 배와 섞여 있다는 것입니다.

자바에서는 어떻게 하면 인쇄가 잘 될까요?

는 ★★★★★★★★★★★★★★★★★★★★★★.String.format("%f", value)값이 작으면 후행 제로가 많이 나오는 것을 제외하고 거의 비슷합니다.

낫다'의 출력 예시입니다.%f

232.000000000.180000000001237875192.0
4.58000000000.000000001.23450000

내가 원하는 것은:

2320.1812378751924.5801.2345

물론 이 0을 잘라내는 함수를 쓸 수 있지만 문자열 조작으로 인해 성능이 크게 저하됩니다.다른 포맷 코드를 더 잘 사용할 수 있을까요?


톰 E.와 제레미 S.의 대답은 둘 다 임의로 소수점 두 자리로 반올림하기 때문에 받아들일 수 없다.답변하기 전에 문제를 이해해 주세요.


해 주세요.String.format(format, args...)로케일에 의존합니다(후술의 답변을 참조).

복수로 저장된 정수를 정수인 것처럼 인쇄하고, 그렇지 않으면 필요한 최소한의 정밀도로 복수를 인쇄하는 방법인 경우:

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

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

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

요컨대:

후행 제로 로케일의 문제를 해소하려면 다음 명령을 사용합니다.

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^72보다^-3보다 크거나 을 사용합니다.

     double myValue = 0.00000021d;
     String.format("%s", myvalue); //output: 2.1E-7
    
  • 를 사용하여%f10시 6시 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
    

    영어 로케일을 사용하면 프로그램이 실행되는 장소에서 소수점 구분자로 포인트를 얻을 수 있습니다.

을 사용하고 , 「340」에 대해서?setMaximumFractionDigits

두 가지 이유:

  • setMaximumFractionDigits정수를 사용할 수 , 그 , 즉 「정수」, 「정수」, 「정수」를 할 수 있습니다.DecimalFormat.DOUBLE_FRACTION_DIGITS340과 같다
  • Double.MIN_VALUE = 4.9E-324따라서 340자리 숫자를 사용하여 2배 반올림하여 정밀도를 잃지 않도록 합니다.

용도:

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

내 의견:

if(n % 1 == 0) {
    return String.format(Locale.US, "%.0f", n));
} else {
    return String.format(Locale.US, "%.1f", n));
}
if (d == Math.floor(d)) {
    return String.format("%.0f", d); //Format is: 0 places after decimal point
} else {
    return Double.toString(d);
}

상세정보 : https://docs.oracle.com/javase/tutorial/java/data/numberformat.html

아뇨, 신경 쓰지 마세요.문자열 조작에 의한 퍼포먼스 손실은 제로입니다.

그리고 여기 끝부분을 자르는 코드가 있습니다%f:

private static String trimTrailingZeros(String number) {
    if(!number.contains(".")) {
        return number;
    }

    return number.replaceAll("\\.?0*$", "");
}
float price = 4.30;
DecimalFormat format = new DecimalFormat("0.##"); // Choose the number of decimal places to work with in case they are different than zero and zero value will be removed
format.setRoundingMode(RoundingMode.DOWN); // Choose your Rounding Mode
System.out.println(format.format(price));

이것은 몇 가지 테스트 결과입니다.

4.30     => 4.3
4.39     => 4.39  // Choose format.setRoundingMode(RoundingMode.UP) to get 4.4
4.000000 => 4
4        => 4

를 사용하다DecimalFormat그리고.setMinimumFractionDigits(0).

이것으로 일을 잘 해낼 수 있습니다.

    public static String removeZero(double number) {
        DecimalFormat format = new DecimalFormat("#.###########");
        return format.format(number);
    }
new DecimalFormat("00.#").format(20.236)
//out =20.2

new DecimalFormat("00.#").format(2.236)
//out =02.2
  1. 0(최소 자리수)
  2. 숫자 렌더링

주의하시기 바랍니다.String.format(format, args...)는 사용자의 기본 로케일을 사용하여 포맷하기 때문에 로케일에 의존합니다.이는 123 456,789 또는 123,456.789같은 콤마 및 내부에 공백이 포함되어 있기 때문입니다.는 예상과는 다를 수 있습니다.

다음을 사용하는 것이 좋습니다.String.format((Locale)null, format, args...).

예를들면,

    double f = 123456.789d;
    System.out.println(String.format(Locale.FRANCE,"%f",f));
    System.out.println(String.format(Locale.GERMANY,"%f",f));
    System.out.println(String.format(Locale.US,"%f",f));

인쇄하다

123456,789000
123456,789000
123456.789000

그리고 이게 바로 우리가String.format(format, args...)다른 나라에서 하다

EDIT OK, 지금까지 격식에 대한 논의가 있었습니다.

    res += stripFpZeroes(String.format((Locale) null, (nDigits!=0 ? "%."+nDigits+"f" : "%f"), value));
    ...

protected static String stripFpZeroes(String fpnumber) {
    int n = fpnumber.indexOf('.');
    if (n == -1) {
        return fpnumber;
    }
    if (n < 2) {
        n = 2;
    }
    String s = fpnumber;
    while (s.length() > n && s.endsWith("0")) {
        s = s.substring(0, s.length()-1);
    }
    return s;
}

제가 만든 건DoubleFormatter다수의 이중 값을 nice/presentable 문자열로 효율적으로 변환하려면:

double horribleNumber = 3598945.141658554548844;
DoubleFormatter df = new DoubleFormatter(4, 6); // 4 = MaxInteger, 6 = MaxDecimal
String beautyDisplay = df.format(horribleNumber);
  • V의 정수 부분이 MaxInteger = >를 초과하는 경우 과학적 형식(1.2345E+30)으로 V를 표시합니다.그렇지 않으면 일반 형식(124.45678)으로 표시합니다.
  • Max Decimal은 십진수를 결정한다(은행가의 반올림).

코드는 다음과 같습니다.

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;

/**
 * Convert a double to a beautiful String (US-local):
 *
 * double horribleNumber = 3598945.141658554548844;
 * DoubleFormatter df = new DoubleFormatter(4,6);
 * String beautyDisplay = df.format(horribleNumber);
 * String beautyLabel = df.formatHtml(horribleNumber);
 *
 * Manipulate 3 instances of NumberFormat to efficiently format a great number of double values.
 * (avoid to create an object NumberFormat each call of format()).
 *
 * 3 instances of NumberFormat will be reused to format a value v:
 *
 * if v < EXP_DOWN, uses nfBelow
 * if EXP_DOWN <= v <= EXP_UP, uses nfNormal
 * if EXP_UP < v, uses nfAbove
 *
 * nfBelow, nfNormal and nfAbove will be generated base on the precision_ parameter.
 *
 * @author: DUONG Phu-Hiep
 */
public class DoubleFormatter
{
    private static final double EXP_DOWN = 1.e-3;
    private double EXP_UP; // always = 10^maxInteger
    private int maxInteger_;
    private int maxFraction_;
    private NumberFormat nfBelow_;
    private NumberFormat nfNormal_;
    private NumberFormat nfAbove_;

    private enum NumberFormatKind {Below, Normal, Above}

    public DoubleFormatter(int maxInteger, int maxFraction){
        setPrecision(maxInteger, maxFraction);
    }

    public void setPrecision(int maxInteger, int maxFraction){
        Preconditions.checkArgument(maxFraction>=0);
        Preconditions.checkArgument(maxInteger>0 && maxInteger<17);

        if (maxFraction == maxFraction_ && maxInteger_ == maxInteger) {
            return;
        }

        maxFraction_ = maxFraction;
        maxInteger_ = maxInteger;
        EXP_UP =  Math.pow(10, maxInteger);
        nfBelow_ = createNumberFormat(NumberFormatKind.Below);
        nfNormal_ = createNumberFormat(NumberFormatKind.Normal);
        nfAbove_ = createNumberFormat(NumberFormatKind.Above);
    }

    private NumberFormat createNumberFormat(NumberFormatKind kind) {

        // If you do not use the Guava library, replace it with createSharp(precision);
        final String sharpByPrecision = Strings.repeat("#", maxFraction_);

        NumberFormat f = NumberFormat.getInstance(Locale.US);

        // Apply bankers' rounding:  this is the rounding mode that
        // statistically minimizes cumulative error when applied
        // repeatedly over a sequence of calculations
        f.setRoundingMode(RoundingMode.HALF_EVEN);

        if (f instanceof DecimalFormat) {
            DecimalFormat df = (DecimalFormat) f;
            DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();

            // Set group separator to space instead of comma

            //dfs.setGroupingSeparator(' ');

            // Set Exponent symbol to minus 'e' instead of 'E'
            if (kind == NumberFormatKind.Above) {
                dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part
            } else {
                dfs.setExponentSeparator("e");
            }

            df.setDecimalFormatSymbols(dfs);

            // Use exponent format if v is outside of [EXP_DOWN,EXP_UP]

            if (kind == NumberFormatKind.Normal) {
                if (maxFraction_ == 0) {
                    df.applyPattern("#,##0");
                } else {
                    df.applyPattern("#,##0."+sharpByPrecision);
                }
            } else {
                if (maxFraction_ == 0) {
                    df.applyPattern("0E0");
                } else {
                    df.applyPattern("0."+sharpByPrecision+"E0");
                }
            }
        }
        return f;
    }

    public String format(double v) {
        if (Double.isNaN(v)) {
            return "-";
        }
        if (v==0) {
            return "0";
        }
        final double absv = Math.abs(v);

        if (absv<EXP_DOWN) {
            return nfBelow_.format(v);
        }

        if (absv>EXP_UP) {
            return nfAbove_.format(v);
        }

        return nfNormal_.format(v);
    }

    /**
     * Format and higlight the important part (integer part & exponent part)
     */
    public String formatHtml(double v) {
        if (Double.isNaN(v)) {
            return "-";
        }
        return htmlize(format(v));
    }

    /**
     * This is the base alogrithm: create a instance of NumberFormat for the value, then format it. It should
     * not be used to format a great numbers of value
     *
     * We will never use this methode, it is here only to understanding the Algo principal:
     *
     * format v to string. precision_ is numbers of digits after decimal.
     * if EXP_DOWN <= abs(v) <= EXP_UP, display the normal format: 124.45678
     * otherwise display scientist format with: 1.2345e+30
     *
     * pre-condition: precision >= 1
     */
    @Deprecated
    public String formatInefficient(double v) {

        // If you do not use Guava library, replace with createSharp(precision);
        final String sharpByPrecision = Strings.repeat("#", maxFraction_);

        final double absv = Math.abs(v);

        NumberFormat f = NumberFormat.getInstance(Locale.US);

        // Apply bankers' rounding:  this is the rounding mode that
        // statistically minimizes cumulative error when applied
        // repeatedly over a sequence of calculations
        f.setRoundingMode(RoundingMode.HALF_EVEN);

        if (f instanceof DecimalFormat) {
            DecimalFormat df = (DecimalFormat) f;
            DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();

            // Set group separator to space instead of comma

            dfs.setGroupingSeparator(' ');

            // Set Exponent symbol to minus 'e' instead of 'E'

            if (absv>EXP_UP) {
                dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part
            } else {
                dfs.setExponentSeparator("e");
            }
            df.setDecimalFormatSymbols(dfs);

            //use exponent format if v is out side of [EXP_DOWN,EXP_UP]

            if (absv<EXP_DOWN || absv>EXP_UP) {
                df.applyPattern("0."+sharpByPrecision+"E0");
            } else {
                df.applyPattern("#,##0."+sharpByPrecision);
            }
        }
        return f.format(v);
    }

    /**
     * Convert "3.1416e+12" to "<b>3</b>.1416e<b>+12</b>"
     * It is a html format of a number which highlight the integer and exponent part
     */
    private static String htmlize(String s) {
        StringBuilder resu = new StringBuilder("<b>");
        int p1 = s.indexOf('.');

        if (p1>0) {
            resu.append(s.substring(0, p1));
            resu.append("</b>");
        } else {
            p1 = 0;
        }

        int p2 = s.lastIndexOf('e');
        if (p2>0) {
            resu.append(s.substring(p1, p2));
            resu.append("<b>");
            resu.append(s.substring(p2, s.length()));
            resu.append("</b>");
        } else {
            resu.append(s.substring(p1, s.length()));
            if (p1==0){
                resu.append("</b>");
            }
        }
        return resu.toString();
    }
}

주의: Guava 라이브러리의 두 가지 기능을 사용했습니다.Guava를 사용하지 않을 경우 직접 코딩하십시오.

/**
 * Equivalent to Strings.repeat("#", n) of the Guava library:
 */
private static String createSharp(int n) {
    StringBuilder sb = new StringBuilder();
    for (int i=0; i<n; i++) {
        sb.append('#');
    }
    return sb.toString();
}
String s = String.valueof("your int variable");
while (g.endsWith("0") && g.contains(".")) {
    g = g.substring(0, g.length() - 1);
    if (g.endsWith("."))
    {
        g = g.substring(0, g.length() - 1);
    }
}

숫자를 이중으로 저장하기로 선택했다고 말씀하셨습니다.정수를 두 배로 저장해야 하기 때문에(따라서 값의 특성에 대한 초기 정보가 손실됨) 이것이 문제의 근원이 될 수 있다고 생각합니다.Number 클래스(Double 및 Integer 모두 슈퍼 클래스)의 인스턴스에 번호를 저장하고 각 번호의 올바른 형식을 결정하기 위해 다형성에 의존하는 것은 어떻습니까?

그렇기 때문에 코드 전체를 리팩터링하는 것은 허용되지 않을 수 있지만, 추가 코드/캐스팅/파싱 없이 원하는 출력을 생성할 수 있습니다.

예제:

import java.util.ArrayList;
import java.util.List;

public class UseMixedNumbers {

    public static void main(String[] args) {
        List<Number> listNumbers = new ArrayList<Number>();

        listNumbers.add(232);
        listNumbers.add(0.18);
        listNumbers.add(1237875192);
        listNumbers.add(4.58);
        listNumbers.add(0);
        listNumbers.add(1.2345);

        for (Number number : listNumbers) {
            System.out.println(number);
        }
    }

}

다음과 같은 출력이 생성됩니다.

232
0.18
1237875192
4.58
0
1.2345

제가 생각해낸 건 다음과 같습니다.

  private static String format(final double dbl) {
    return dbl % 1 != 0 ? String.valueOf(dbl) : String.valueOf((int) dbl);
  }

심플한 원라이너로 꼭 필요한 경우에만 삽입할 수 있습니다.

불필요한 0이 없는 그룹화, 반올림(중복)으로 가격을 포맷합니다.

규칙:

  1. 이 없습니다(끝에0 no( 0 (( (( (( (( ( no 。2.0000 = 2; 1.0100000 = 1.01)
  2. ('' ')2.010 = 2.01; 0.20 = 0.2)
  3. 의 두 (반올림)1.994 = 1.99; 1.995 = 2; 1.006 = 1.01; 0.0006 -> 0)
  4. 0 )null/-0 = 0)
  5. " " 를 합니다.$ )= $56/-$56)
  6. 룹룹( grouping grouping grouping)101101.02 = $101,101.02)

기타 예:

-99.985 = -$99.99

10 = $10

10.00 = $10

20.01000089 = $20.01

Kotlin에서는 Double(안드로이드에서 사용되기 때문에)의 재미있는 확장으로 쓰여져 있습니다만, Java 클래스가 사용되었기 때문에 쉽게 Java로 변환할 수 있습니다.

/**
 * 23.0 -> $23
 *
 * 23.1 -> $23.1
 *
 * 23.01 -> $23.01
 *
 * 23.99 -> $23.99
 *
 * 23.999 -> $24
 *
 * -0.0 -> $0
 *
 * -5.00 -> -$5
 *
 * -5.019 -> -$5.02
 */
fun Double?.formatUserAsSum(): String {
    return when {
        this == null || this == 0.0 -> "$0"
        this % 1 == 0.0 -> DecimalFormat("$#,##0;-$#,##0").format(this)
        else -> DecimalFormat("$#,##0.##;-$#,##0.##").format(this)
    }
}

사용방법:

var yourDouble: Double? = -20.00
println(yourDouble.formatUserAsSum()) // will print -$20

yourDouble = null
println(yourDouble.formatUserAsSum()) // will print $0

Decimal Format에 대해서:https://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html

Kotlin의 경우 다음과 같은 확장을 사용할 수 있습니다.

fun Double.toPrettyString() =
    if(this - this.toLong() == 0.0)
        String.format("%d", this.toLong())
    else
        String.format("%s", this)

다음은 소수점이 0이 아닌 경우에만 소수점을 추가하는 옵션이 있는 다른 답변입니다.

   /**
     * Example: (isDecimalRequired = true)
     * d = 12345
     * returns 12,345.00
     *
     * d = 12345.12345
     * returns 12,345.12
     *
     * ==================================================
     * Example: (isDecimalRequired = false)
     * d = 12345
     * returns 12,345 (notice that there's no decimal since it's zero)
     *
     * d = 12345.12345
     * returns 12,345.12
     *
     * @param d float to format
     * @param zeroCount number decimal places
     * @param isDecimalRequired true if it will put decimal even zero,
     * false will remove the last decimal(s) if zero.
     */
    fun formatDecimal(d: Float? = 0f, zeroCount: Int, isDecimalRequired: Boolean = true): String {
        val zeros = StringBuilder()

        for (i in 0 until zeroCount) {
            zeros.append("0")
        }

        var pattern = "#,##0"

        if (zeros.isNotEmpty()) {
            pattern += ".$zeros"
        }

        val numberFormat = DecimalFormat(pattern)

        var formattedNumber = if (d != null) numberFormat.format(d) else "0"

        if (!isDecimalRequired) {
            for (i in formattedNumber.length downTo formattedNumber.length - zeroCount) {
                val number = formattedNumber[i - 1]

                if (number == '0' || number == '.') {
                    formattedNumber = formattedNumber.substring(0, formattedNumber.length - 1)
                } else {
                    break
                }
            }
        }

        return formattedNumber
    }

로케일을 염두에 둔 심플한 솔루션:

double d = 123.45;
NumberFormat numberFormat = NumberFormat.getInstance(Locale.GERMANY);
System.out.println(numberFormat.format(d));

독일에서는 콤마가 십진수 구분자로 사용되기 때문에 위는 다음과 같이 인쇄됩니다.

123,45

여기 그것을 성취하는 두 가지 방법이 있다.첫째, 더 짧은(아마도 더 나은) 방법:

public static String formatFloatToString(final float f)
{
  final int i = (int)f;
  if(f == i)
    return Integer.toString(i);
  return Float.toString(f);
}

그리고 더 길고 더 나쁜 방법이 있습니다.

public static String formatFloatToString(final float f)
{
  final String s = Float.toString(f);
  int dotPos = -1;
  for(int i=0; i<s.length(); ++i)
    if(s.charAt(i) == '.')
    {
      dotPos = i;
      break;
    }

  if(dotPos == -1)
    return s;

  int end = dotPos;
  for(int i = dotPos + 1; i<s.length(); ++i)
  {
    final char c = s.charAt(i);
    if(c != '0')
      end = i + 1;
  }
  final String result = s.substring(0, end);
  return result;
}
public static String fmt(double d) {
    String val = Double.toString(d);
    String[] valArray = val.split("\\.");
    long valLong = 0;
    if(valArray.length == 2) {
        valLong = Long.parseLong(valArray[1]);
    }
     if (valLong == 0)
        return String.format("%d", (long) d);
    else
        return String.format("%s", d);
}

는 이것을 하지 않을 수 .d == (long)d음파탐지기 보고서를 위반하고 있었어요

는 JSF 어플리케이션에서 0 뒤에 붙지 않고 숫자 포맷을 하기 위해 이것을 사용하고 있습니다.원래의 내장 포맷에서는, 소수 자릿수의 최대수를 지정할 필요가 있었습니다.이 값은 소수 자릿수가 너무 많은 경우에도 도움이 될 수 있습니다.

/**
 * Formats the given Number as with as many fractional digits as precision
 * available.<br>
 * This is a convenient method in case all fractional digits shall be
 * rendered and no custom format / pattern needs to be provided.<br>
 * <br>
 * This serves as a workaround for {@link NumberFormat#getNumberInstance()}
 * which by default only renders up to three fractional digits.
 *
 * @param number
 * @param locale
 * @param groupingUsed <code>true</code> if grouping shall be used
 *
 * @return
 */
public static String formatNumberFraction(final Number number, final Locale locale, final boolean groupingUsed)
{
    if (number == null)
        return null;

    final BigDecimal bDNumber = MathUtils.getBigDecimal(number);

    final NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
    numberFormat.setMaximumFractionDigits(Math.max(0, bDNumber.scale()));
    numberFormat.setGroupingUsed(groupingUsed);

    // Convert back for locale percent formatter
    return numberFormat.format(bDNumber);
}

/**
 * Formats the given Number as percent with as many fractional digits as
 * precision available.<br>
 * This is a convenient method in case all fractional digits shall be
 * rendered and no custom format / pattern needs to be provided.<br>
 * <br>
 * This serves as a workaround for {@link NumberFormat#getPercentInstance()}
 * which does not renders fractional digits.
 *
 * @param number Number in range of [0-1]
 * @param locale
 *
 * @return
 */
public static String formatPercentFraction(final Number number, final Locale locale)
{
    if (number == null)
        return null;

    final BigDecimal bDNumber = MathUtils.getBigDecimal(number).multiply(new BigDecimal(100));

    final NumberFormat percentScaleFormat = NumberFormat.getPercentInstance(locale);
    percentScaleFormat.setMaximumFractionDigits(Math.max(0, bDNumber.scale() - 2));

    final BigDecimal bDNumberPercent = bDNumber.multiply(new BigDecimal(0.01));

    // Convert back for locale percent formatter
    final String strPercent = percentScaleFormat.format(bDNumberPercent);

    return strPercent;
}

지정된 소수점 길이로 작업...

public static String getLocaleFloatValueDecimalWithLength(Locale loc, float value, int length) {
        //make string from float value
        return String.format(loc, (value % 1 == 0 ? "%.0f" : "%."+length+"f"), value);
    }

실제 효과가 있는 답변은 다음과 같습니다(여기에는 다양한 답변의 조합).

public static String removeTrailingZeros(double f)
{
    if(f == (int)f) {
        return String.format("%d", (int)f);
    }
    return String.format("%f", f).replaceAll("0*$", "");
}

이를 위한 최선의 방법은 다음과 같습니다.

public class Test {

    public static void main(String args[]){
        System.out.println(String.format("%s something", new Double(3.456)));
        System.out.println(String.format("%s something", new Double(3.456234523452)));
        System.out.println(String.format("%s something", new Double(3.45)));
        System.out.println(String.format("%s something", new Double(3)));
    }
}

출력:

3.456 something
3.456234523452 something
3.45 something
3.0 something

유일한 문제는 0.0이 제거되지 않는 마지막 문제입니다.단, 이 기능을 사용할 수 있다면 이 방법이 가장 적합합니다.%2f는 소수점 이하 두 자리까지 반올림합니다.Decimal Format도 마찬가지입니다.모든 소수 자릿수가 필요하지만 후행 0이 아닌 경우 이 방법이 가장 적합합니다.

String s = "1.210000";
while (s.endsWith("0")){
    s = (s.substring(0, s.length() - 1));
}

그러면 후행0-s를 폐기하는 문자열이 생성됩니다.

언급URL : https://stackoverflow.com/questions/703396/how-to-nicely-format-floating-numbers-to-string-without-unnecessary-decimal-0s

반응형