Java:如何使用第十个指数格式化字符串数

时间:2011-03-17 13:53:32

标签: java string number-formatting

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

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

同样正确的舍入会很好。

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

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

2 个答案:

答案 0 :(得分:3)

我无法找到能够涵盖您所描述的所有案例的单一格式模式。但这是我认为有效的逻辑组合:

   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

答案 1 :(得分: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等)的后缀