【问题标题】:Java: How to format String number with tenth exponentJava:如何用第十个指数格式化字符串数字
【发布时间】:2011-03-17 13:53:31
【问题描述】:

我有一个数字作为这样的字符串:“9.756088256835938E-4”但我只能使用指定数量的字符(在这种特殊情况下为 9 个字符)。所以我想要这样的东西:“9.7561E-4”。我已经尝试将 String 转换为 Double ,然后使用 format 方法来获得更少的字符,但我没有正确的解决方案。

问题是我需要十个指数输出,因为有些数字比我拥有的字符数长。如果可能,数字应该不显示十个指数,如果不是只使用十个指数。

正确的舍入也很好。

它应该适用于负数。 (减去需要一个字符!!!)

是否有可以定义输出字符串最大长度的格式函数?有什么想法吗?

【问题讨论】:

标签: java string number-formatting


【解决方案1】:

我很难找到涵盖您描述的所有情况的单一格式模式。但这是我认为可行的逻辑组合:

   public static void main(String[] args) throws Exception {
      // 97.560883
      System.out.println(formatNum(Double.parseDouble("9.756088256835938E+1")));
      // 9.756E+11
      System.out.println(formatNum(Double.parseDouble("9.756088256835938E+11"))); 
      // 0.0009756
      System.out.println(formatNum(Double.parseDouble("9.756088256835938E-4")));  
      // -9.8E+111
      System.out.println(formatNum(Double.parseDouble("-9.756088256835938E+111")));
   }

   private static final int MAX_LENGTH = 9;

   private static String formatNum(double number) {
      String out = null;
      for ( int i = 0; i < MAX_LENGTH; i++ ) {
         String format = "%." + i + "G";
         out = String.format(format, number);
         if ( out.length() == MAX_LENGTH ) {
            return out;
         }
      }
      return out; //the best we can do
   }

模式中的“G”指示格式化程序在允许相同或更好的精度时放弃使用指数。我们增长到最大长度并在输出字符串为 10 个字符时停止。我认为您可以对DecimalFormat 采取相同的方法,但我更熟悉Formatter

【讨论】:

  • 不错的功能,但你知道为什么 String.format(format, number);当 number = 0 时抛出 java.lang.ArrayIndexOutOfBoundsException?
【解决方案2】:

看到 Mark 的示例满足您的要求,我更新了答案以显示 DecimalFormat 实现。我使用了 Mark 的测试用例。这绝对是一个丑陋的选择,因为没有简单的方法来打开/关闭指数。与 String.format 选项相比的唯一优势是它可以很好地处理非常小的数字。

public static void main(String[] args) throws Exception {
    // 97.560883
    System.out.println(formatNum(Double.parseDouble("9.756088256835938E+1")));
    // 9.756E+11
    System.out.println(formatNum(Double.parseDouble("9.756088256835938E+11")));
    // 0.0009756
    System.out.println(formatNum(Double.parseDouble("9.756088256835938E-4")));
    // -9.8E+111
    System.out.println(formatNum(Double.parseDouble("-9.756088256835938E+111")));
}

private static final int MAX_LENGTH = 9;

private static String formatNum(double number) {
    int digitsAvailable = MAX_LENGTH - 2;
    if (Math.abs(number) < Math.pow(10, digitsAvailable)
            && Math.abs(number) > Math.pow(10, -digitsAvailable)) {
        String format = "0.";
        double temp = number;
        for (int i = 0; i < digitsAvailable; i++) {
            if ((temp /= 10) < 1) {
                format += "#";
            }
        }
        return new DecimalFormat(format).format(number);
    }
    String format = "0.";
    for (int i = 0; i < digitsAvailable; i++) {
            format += "#";
    }
    String r = new DecimalFormat(format + "E0").format(number);
    int lastLength = r.length() + 1;
    while (r.length() > MAX_LENGTH && lastLength > r.length()) {
        lastLength = r.length();
        r = r.replaceAll("\\.?[0-9]E", "E");
    }
    return r;
}

这让我想起了similar question,其中 OP 只有 5 个左右的空格来表示一个数字,并且只有在有足够的空间时才想显示一个小数。但不是指数,而是想使用 (k,m, etc) 的后缀

【讨论】:

  • 是的,您的链接似乎实现了类似的。我没有在我的上下文中找到这篇文章,我最初是在寻找一个开箱即用的 java 函数(似乎没有),因为标准双转换似乎也在第十指数和正常格式之间自动切换。我想到了配置标准行为的可能性。谢谢
猜你喜欢
  • 2014-09-28
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多