【问题标题】:Java - Include decimal and preceding digits when setting length of double to be printed?Java - 设置要打印的双精度时包括小数和前面的数字?
【发布时间】:2017-05-11 11:14:54
【问题描述】:

我正在打印一个矩阵,每个元素在屏幕上打印的长度相同,以便于阅读。

如果我这样做:

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

然后我得到不同的长度,具体取决于前面的(整体)值:

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

提供以下输出:

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

这使矩阵变得混乱。如何将整个双精度数(包括小数和整数)限制为一定长度?因此,对于前面的情况,输出将是:

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

编辑#1

我不想只用零填充。前导零没有吸引力,可能会导致误读。即使我现在有%.16f,我可能会使用较少的精度,并且每个数字都是重要的(并且非零)。

【问题讨论】:

  • Right pad with zeros的可能重复
  • 但是如果你指定你想要 16 位小数,你会期待什么呢? %.16f

标签: java printf double


【解决方案1】:

有不同的方式来格式化输出(但与你的输出不完全相同):

  1. 使用printf方法(假设21位宽度):

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

    => 输出

       1.0000000000000000
2.3450000000000000
10.0000000000000000
1243.5678000000000000

  1. 使用 Apache Commons Lang 库。假设您希望小数点后有 16 位,小数点前有 5 位,可能会产生以下结果:

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

输出:

1.0000000000000000000
2.3450000000000000000
10.000000000000000000
1243.5678000000000000

  1. 另一种方式是使用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));
    

    和输出:

00001.0000000000000000
00002.3450000000000000
00010.0000000000000000
01243.5678000000000000

【讨论】:

  • Printf 可以前缀零: System.out.printf("%021.16f%n", 1.0);无需查找,这应该使用至少 21 位数字打印该号码。大多数 16 都在 .和 5 之前。当数字在 .格式被扩展...
  • @Matthias 我知道,但我认为 OP 对领先的 0s 不感兴趣(请参阅问题中他想要的输出)。无论如何,谢谢你的建议。
  • 很难说谁的解决方案更好,但我真的很喜欢你提出的第一个选项的外观,小数对齐。非常感谢。
【解决方案2】:

一种选择是链接两个字符串格式化调用。第一个调用是:

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

这将给出具有 16 位精度的浮点的任意宽度字符串表示。下一次调用应该给出一个固定宽度的 18 个字符的字符串,如果需要,它会被右截断。

System.out.format("%18s : %s", String.format("%.16f", x));

【讨论】:

    【解决方案3】:

    您应该为此使用 BigDecimal。

    类似这样的:

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

    您可以阅读更多关于它的信息here:

    您可以将上面的Double转换为String,然后将String转换为BigDecimal。

    您可以阅读此post 了解更多详情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多