Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Formatting numbers with same amount of padding

Tags:

java

I want to format 3 digit floats in Java so they line up vertically such that they look like:

123.45
 99
 23.2
 45

When I use DecimalFormat class, I get close, but I want to insert spaces when the item has 1 or 2 digits.

My code:

DecimalFormat formatter = new java.text.DecimalFormat("####.##");
float [] floats = [123.45, 99.0, 23.2, 45.0];

for(int i=0; i<floats.length; i++)
{
    float value = floats[i];

    println(formatter.format(value));
}

It produces:

123.45
99
23.2
45

How can I print it so that all but the first line is shifted over by 1 space?

like image 314
sarasota Avatar asked Jul 26 '10 22:07

sarasota


2 Answers

Try with String.format() (JavaDoc):

public static void main(String args[]){
  String format = "%10.2f\n";  // width == 10 and 2 digits after the dot
  float [] floats = {123.45f, 99.0f, 23.2f, 45.0f};
  for(int i=0; i<floats.length; i++) {
      float value = floats[i];
      System.out.format(format, value);
}

and the output is :

123.45
 99.00
 23.20
 45.00
like image 124
RealHowTo Avatar answered Sep 30 '22 03:09

RealHowTo


This is trivial with a bit of regular expression string replacement.

formatter.format(f).replaceAll("\\G0", " ")

Here it is in context: (see also on ideone.com):

    DecimalFormat formatter = new java.text.DecimalFormat("0000.##");
    float[] floats = {
        123.45f,     //  123.45
         99.0f,      //   99
         23.2f,      //   23.2
         12.345f,    //   12.35
           .1234f,   //     .12
        010.001f,    //   10
    };

    for(float f : floats) {
        String s = formatter.format(f).replaceAll("\\G0", " ");
        System.out.println(s);
    }

This uses DecimalFormat to do most of the formatting (the zero padding, the optional #, etc) and then uses String.replaceAll(String regex, String replacement) to replace all leading zeroes to spaces.

The regex pattern is \G0. That is, 0 that is preceded by \G, which is the "end of previous match" anchor. The \G is also present at the beginning of the string, and this is what allows leading zeroes (and no other zeroes) to be matched and replaced with spaces.

References

  • java.util.regex.Pattern
  • regular-expressions.info - Continuing Matches

On escape sequences

The reason why the pattern \G0 is written as "\\G0" as a Java string literal is because the backslash is an escape character. That is, "\\" is a string of length one, containing the backslash.

References

  • JLS 3.10.6 Escape Sequences for Character and String Literals

Related questions

  • How to replace a special character with single slash
  • Is the char literal '\"' the same as '"' ?(backslash-doublequote vs only-doublequote)

Additional tips

Note that I've used the for-each loop, which results in a much simpler code, thus enhancing readability and minimizing chances of mistakes. I've also kept the floating point variables as float, using the f suffix to declare them as float literals (since they're double by default otherwise), but it needs to be said that generally you should prefer double to float.

See also

  • Java Language Guide/For-each loop
  • Java Puzzlers: Prefer double to float.
like image 22
polygenelubricants Avatar answered Sep 30 '22 03:09

polygenelubricants