Format, 2 decimal places for double and 0 for inte

2019-02-24 11:48发布

问题:

I am trying to format a double to exact 2 decimal places if it has fraction, and cut it off otherwise using DecimalFormat

So, I'd like to achieve next results:

100.123 -> 100.12
100.12  -> 100.12
100.1   -> 100.10
100     -> 100

Variant #1

DecimalFormat("#,##0.00")

100.1 -> 100.10
but
100   -> 100.00

Variant #2

DecimalFormat("#,##0.##")

100   -> 100
but
100.1 -> 100.1

Have any ideas what pattern to choose in my case?

回答1:

The only solution i reached is to use if statement like was mentioned here: https://stackoverflow.com/a/39268176/6619441

public static boolean isInteger(BigDecimal bigDecimal) {
    int intVal = bigDecimal.intValue();
    return bigDecimal.compareTo(new BigDecimal(intVal)) == 0;
}

public static String myFormat(BigDecimal bigDecimal) {
    String formatPattern = isInteger(bigDecimal) ? "#,##0" : "#,##0.00";
    return new DecimalFormat(formatPattern).format(bigDecimal);
}

Testing

myFormat(new BigDecimal("100"));   // 100
myFormat(new BigDecimal("100.1")); // 100.10

If someone knows more elegant way, please share it!



回答2:

I believe we need an if statement.

static double intMargin = 1e-14;

public static String myFormat(double d) {
    DecimalFormat format;
    // is value an integer?
    if (Math.abs(d - Math.round(d)) < intMargin) { // close enough
        format = new DecimalFormat("#,##0.##");
    } else {
        format = new DecimalFormat("#,##0.00");
    }
    return format.format(d);
}

The margin allowed for a number to be regarded as an integer should be chosen according to the situation. Just don’t assume you will always have an exact integer when you expect one, doubles don’t always work that way.

With the above declaration myFormat(4) returns 4, myFormat(4.98) returns 4.98 and myFormat(4.0001) returns 4.00.