0

I'm printing out a matrix, with each element having the same length printed on screen for easier reading.

If I do something like:

System.out.printf("%.16f", x);

then I get different lengths, depending on the preceding (whole) values:

x = 1;
x = 2.345;
x = 10;
x = 1243.5678;

gives the following outputs:

// 1.0000000000000000
// 2.3450000000000000
// 10.0000000000000000
// 1243.5678000000000000

which makes the matrix all messy. How can I limit the entire double - including the decimal and whole number - to a certain length? So, for the previous cases, the outputs would be:

// 1.0000000000000000
// 2.3450000000000000
// 10.000000000000000
// 1243.5678000000000

Edit #1

I don't want to just pad with zeros. Leading zeros are unattractive and can cause misreads. And even though I have %.16f right now, I may use less precision, and each digit will be significant (and non-zero).

Birrel
  • 4,464
  • 5
  • 27
  • 62
  • 1
    Possible duplicate of [Right pad with zeros](http://stackoverflow.com/questions/12962515/right-pad-with-zeros) – shmosel Dec 27 '16 at 07:12
  • But what do you expect if you specify that you want 16 decimals? `%.16f` – ACV Dec 27 '16 at 10:31

3 Answers3

2

One option is to chain two string formatting calls. The first call is:

String.format("%.16f", x)

This will give an arbitrary width string representation of a float with 16 places of precision. The next call should give a fixed width string of 18 characters which is right truncated, if necessary.

System.out.format("%18s : %s", String.format("%.16f", x));
Tim Biegeleisen
  • 387,723
  • 20
  • 200
  • 263
2

There are different ways to format the output (but not exactly the same as your output):

  1. Using printf method (assuming 21 digits width):

    System.out.printf("%21.16f%n", 1.0);
    System.out.printf("%21.16f%n", 2.345);
    System.out.printf("%21.16f%n", 10.0);
    System.out.printf("%21.16f", 1243.5678);
    

    => output

       1.0000000000000000
       2.3450000000000000
     10.0000000000000000
 1243.5678000000000000

  1. Use Apache Commons Lang library. Assuming you want to have 16 digits after the decimal point and 5 digits before it, the following might produce:

    System.out.println(StringUtils.rightPad(String.valueOf(1.0), 21, '0'));
    System.out.println(StringUtils.rightPad(String.valueOf(2.345), 21, '0'));
    System.out.println(StringUtils.rightPad(String.valueOf(10.0), 21, '0'));
    System.out.println(StringUtils.rightPad(String.valueOf(1243.5678), 21, '0'));
    

the output:

1.0000000000000000000
2.3450000000000000000
10.000000000000000000
1243.5678000000000000

  1. The other way is to use DecimalFormat:

    final String format = "00000.0000000000000000";
    DecimalFormat formatter = new DecimalFormat(format);
    System.out.println(formatter.format(1.0));
    System.out.println(formatter.format(2.345));
    System.out.println(formatter.format(10.0));
    System.out.println(formatter.format(1243.5678));
    

    and the ouput:

00001.0000000000000000
00002.3450000000000000
00010.0000000000000000
01243.5678000000000000

ujulu
  • 3,154
  • 2
  • 9
  • 14
  • Printf can prefix zeros: System.out.printf("%021.16f%n", 1.0); Without looking it up this should print the number using at least 21 digits. From most 16 are after the . and 5 before. When the number has more degits before the . the format is expanded... – Matthias Dec 27 '16 at 12:41
  • @Matthias I know, but I thought the OP is not interested in the leading `0`s (see his desired output in the question). Anyway, thanks for the sugesstion. – ujulu Dec 27 '16 at 13:04
  • Difficult to say who's solutions are better, but I really like the look of the first option you presented, with the decimals aligned. Much thanks. – Birrel Dec 27 '16 at 17:00
0

You should use BigDecimal for that.

Something like this:

BigDecimal db = new BigDecimal(d).setScale(6, BigDecimal.ROUND_HALF_UP);

You can read more about it here:.

You can convert the above Double to String and then convert the String to BigDecimal.

You can read this post for more details.

Community
  • 1
  • 1
Pritam Banerjee
  • 15,297
  • 10
  • 71
  • 92