tgabb
tgabb

Reputation: 379

Java Format Specifier for Limiting Trailing Zeros to 1

I'm looking for a format specifier to limit the number of trailing zeros after a decimal to just 1, but if they aren't all zeros then truncate to two.

Like so:

127.000000 -> 127.0

0.000000 -> 0.0

123.456 -> 123.45

I Have tried taking care of it with logic but it doesn't seem to work.

call my number result and use the following logic:

    if(result - (int)result == 0){
        output = String.format("%.1f\n",result);
    }
    else{
        output = String.format("%.2f\n,result);
    }

sometimes this logic works, and sometimes it doesnt. For example

(int)result - result == 0 is true for 0.000000

but false for 127.000000

Any ideas?

Upvotes: 4

Views: 5288

Answers (5)

scriber36
scriber36

Reputation: 135

I know I'm late from the party now 5 and a half years later, but someone might find it useful, as I've found my way here too.

Method 1: NumberFormat

double value = 1234.5678;

NumberFormat formatter1 = new DecimalFormat("##.0");
String text1 = formatter1.format(value); // "1234.6"

NumberFormat formatter2 = new DecimalFormat("##.00");
String text2 = formatter2.format(value); // "1234.57"

Rounding approach is optionally configurable:

formatter.setRoundingMode(RoundingMode.CEILING);
// UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UNNECESSARY

Using this, we can modify the code a little bit to achieve the desired behavior:

double value = 127.12;
NumberFormat formatter = new DecimalFormat("##.00");
formatter.setRoundingMode(RoundingMode.FLOOR);
String output = (value == (int) value)
    ? Double.toString(value)
    : formatter.format(value);

This meets your requirements. One thing to mention, for 123.4 it returns 123.40. If you'd like to prevent this, we can do the integer comparison with a shifted decimal dot:

double value = 127.12;
NumberFormat formatter = new DecimalFormat("##.00");
formatter.setRoundingMode(RoundingMode.FLOOR);
String output = (value * 10 == (int) (value * 10))
    ? Double.toString(value)
    : formatter.format(value);

This returns "127.0" for 127.000000, "0.0" for 0.000000, "123.45" for 123.456 and also "123.4" for 123.4.

Method 2: Simple Java

It's not the nicest way, but maybe the shortest? Previously I just did:

double value = 1234.56789;
String text = Double.toString(Math.round(value * 10.0) / 10.0); // "1234.6"

Same with keeping at most 2 digits:

double value = 1234.56789;
String text = Double.toString(Math.round(value * 100.0) / 100.0); // "1234.57"

This way we explicitly round the number to a desired precision. We can truncate it too:

double value = 1234.56789;
String text = Double.toString(((int) (value * 10.0) / 10.0)); // "1234.5"

One could argue, that making a multiplication and a division is a waste of computational power, but I guess it's still faster than modifying the result string, removing trailing zeros, etc. Also, since floating points are stored in memory in binary format and not decimal, running * 10.0 / 10.0 might not result the exact same number.

Upvotes: 0

kyleus
kyleus

Reputation: 1051

Here is a Regex that works:

public class DecimalTest {

private static Pattern PATTERN = Pattern.compile("(\\d+\\.)(0|\\d\\d)");
private static final String[] TEST_VALUES = {"127.000000", "0.0000000", "123.456"};

public static void main(String[] args) {

    for (final String testValue : TEST_VALUES) {
        final Matcher matcher = PATTERN.matcher(testValue);
        if (matcher.find())
            System.out.println(matcher.group(1) + matcher.group(2));
        }
    }
}

Upvotes: 0

jrook
jrook

Reputation: 3519

Since you want at most two digits after the decimal point, you can first cut the rest out and then decide if you want to keep the last digit or not.

    float result = 127.8901f; //0.0000 
    String output = String.format("%.2f", result);
    if (output.endsWith("00")) output = output.substring(0,output.length()-1);

Upvotes: 1

Ravi
Ravi

Reputation: 31407

You can convert it to string and look for . index

    String n1 = new String("127.000000");
    String output=null;

    if(n1.charAt(n1.indexOf(".")+2)>'0') //after decimal if non-zero at second position
    {
        output= n1.substring(0,n1.indexOf(".")+3);
    }
    else
    {
        output= n1.substring(0,n1.indexOf(".")+2);  
    }

    System.out.println(output);

Upvotes: 0

Roman Danilov
Roman Danilov

Reputation: 371

What about NumberFormat?

NumberFormat formatter = NumberFormat.getNumberInstance(Locale.ROOT);
formatter.setMinimumFractionDigits(1);
formatter.setMaximumFractionDigits(2);
String s1 = formatter.format(127.000000);
String s2 = formatter.format(0.000000);
String s3 = formatter.format(123.456);
System.out.println(s1);     //prints 127.0
System.out.println(s2);     //prints 0.0
System.out.println(s3);     //prints 123.46

Upvotes: 5

Related Questions