Что такое шаблон MessageFormat для создания локализованного вывода с полной точностью для любого двойного

Учитывая код примера:

String format = "{0,number}"; // <- What do I put here?
double value = Math.PI * 1e-10;
System.out.println(value);
System.out.println(new MessageFormat(format, Locale.US).format(new Object[]{value}));
System.out.println(new MessageFormat(format, Locale.FRANCE).format(new Object[]{value}));

Что мне использовать в качестве строки формата, чтобы получить вывод с полной точностью любого двойного значения и чтобы вывод был локализован? Например, вывод текущего кода:

3.1415926535897934E-10
0
0

String.valueOf(double) правильно печатает полную точность, но это не формат сообщения и он не локализован. Формат сообщения решает, что значение слишком мало, чтобы возиться с ним. Для больших чисел результаты еще хуже! MessageFormat печатает 16 значащих цифр, а затем добавляет кучу нулей, которые не точно отражают значение, хранящееся в двойном значении. Например. с pi * 1e100 я получаю:

3.141592653589793E100
31,415,926,535,897,930,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
31 415 926 535 897 930 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000

person Evan    schedule 19.12.2018    source источник
comment
Возможно: stackoverflow.com/questions/22513607/ будет полезен.   -  person John M I Davis    schedule 19.12.2018


Ответы (1)


Для вашего требования и только для него это самое простое решение, которое подходит для вашего кода.

Используя символ # ниже, мы показываем цифры только тогда, когда они не равны 0, в противном случае они опускаются.

double value = Math.PI*1e-10;
        String format = "{0,number,#.###############E0}"; // <- What do I put here?

        System.out.println(value);
        System.out.println(new MessageFormat(format, Locale.US).format(new Double[]{value}));
        System.out.println(new MessageFormat(format, Locale.FRANCE).format(new Double[]{value}));

Если вы хотите пропустить преобразование чисел форматирования с помощью научных уведомлений, например, вместо 9.424777960769379E2 (если в формате #.###############E0) или 94.24777960769379E1 (если в формате # #.###############E0 ) будет 942.4777960769379, просто используйте код ниже:

        double value = Math.PI*1e-10;
        String format = "{0,number,#.################}"; // <- What do I put here?

Посмотрите, и если есть что-то, что вам нужно дополнительно, не стесняйтесь спрашивать!

person MS90    schedule 19.12.2018
comment
ваш второй пример не выводит полную точность. Хорошее замечание по научной нотации. Это все еще не так хорошо, как Double.toString(), который решает, использовать ли экспоненциальное представление на основе величины значения. - person Evan; 21.12.2018