Java: Как отформатировать строковое число с десятой степенью - PullRequest
0 голосов
/ 17 марта 2011

У меня есть число в виде строки типа: «9.756088256835938E-4», но я могу использовать только указанное количество символов (в этом особом случае 9 символов).Поэтому я хочу что-то вроде этого: «9.7561E-4».Я уже пытался преобразовать String в Double, а затем использовал метод форматирования, чтобы получить меньше символов, но у меня нет правильного решения.

Проблема в том, что мне нужно десять экспоненциальных выходных данных, так как некоторые числабольше, чем количество символов у меня есть.Если это возможно, число должно отображаться без десятичной степени, если не просто использовать десятичную.

Также было бы правильным правильное округление.

И оно должно работать для отрицательных чисел.(минус нужен один символ !!!)

Есть ли функция форматирования, где я могу определить максимальную длину выходной строки?Есть идеи?

Ответы [ 2 ]

3 голосов
/ 17 марта 2011

У меня проблемы с поиском единого шаблона формата, который охватит все случаи, которые вы описали.Но вот комбинация логики, которая, я думаю, работает:

   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.

2 голосов
/ 17 марта 2011

Видя, что пример Mark соответствует вашим требованиям, я обновил свой ответ, чтобы показать реализацию DecimalFormat. Я использовал тестовые наборы Марка. Это определенно более уродливый вариант, потому что нет простого способа включить / выключить показатели. Единственное преимущество перед опцией 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;
}

Это напомнило мне о подобном вопросе , где у ОП было только 5 или около того пробелов для числа, и он хотел показывать десятичную дробь только тогда, когда было достаточно места. Но вместо показателей хотел использовать суффикс (k, m и т. Д.)

...