Как вывести локализованные значения Java с плавающей запятой с полной точностью?

Если я отформатирую двойной, используя toString метод, то я получаю полную точность двойной. Например (используя синтаксис Scala):

java.text.MessageFormat.format ("{0}", Math.PI.toString)

приведет к строке, содержащей:

3.141592653589793

Однако это значение не локализовано. Если я передам двойное значение в штучной упаковке Doubleэто как:

java.text.MessageFormat.format ("{0}", Math.PI.asInstanceOf[AnyRef])

(AnyRef это тип Scala, который эквивалентен Object в Java), то результатом будет локализованная строка с усеченной точностью:

3.142

Результат тот же, даже если я добавлю больше подсказки к строке формата:

java.text.MessageFormat.format ("{0,number}", Math.PI.asInstanceOf[AnyRef])

Я могу получить полную точность, указав пользовательский формат:

java.text.MessageFormat.format ("{0,number,#.###############}", Math.PI.asInstanceOf[AnyRef])

но это требует некоторых знаний о величине и точности двойника. Если я печатаю любое двойное значение (не только Pi) и хочу сохранить полную точность значения, то этот подход означает, что мне нужно динамически изменять строку формата - и это не совсем удобно, если (как в моем случае) строка формата фактически получена из пакета ресурсов.

Например, рассмотрим двойное значение 1.0e37, Сначала преобразование в строку и использование "{0}" в качестве строки формата приводит к соответствующему, но не локализованному, строковому значению 1.0E37, Если я передам это в штучной упаковке Double со строкой формата "{0, число}", тогда я получаю смешное значение 10,000,000,000,000,000,000,000,000,000,000,000,000,

Короче говоря, я не могу найти строку формата, которая сохраняет полную точность двойного без предварительного преобразования ее в строку - и это то, что я предпочел бы избежать, как чума. Есть ли строка числового формата, которая выводит полную точность двойного в качестве локализованного значения?

ОБНОВЛЕНИЕ:

Просто чтобы уточнить, почему я предпочел бы не преобразовывать двойные числа в строки:

  • toString насколько я могу судить, возвращает действительное двойное литеральное значение Java. Как строка, результат не локализуется при передаче MessageFormat.format, Например, я говорю, что я хочу вывести локализованную форму значения 1234.567, toString вернется "1234.567", а также MessageFormat.format оставил бы это в этом. Хорошо. У меня есть точный вывод. Однако в Германии это было бы более разумно, если бы "1.234,567", Даже в США / Великобритании это выглядело бы лучше, если бы "1,234.567",
  • Если я пройду в штучной упаковке Integer, Booleanили любой другой не примитивный тип с плавающей точкой MessageFormat.format (с простым форматом "{n}"), тогда я получаю хорошо локализованный вывод с полной точностью. Мне не нужно - и не следует, поскольку я потеряю локализованный вывод - сначала преобразовать эти значения в строки. Это означает, что я должен лечить двойников (и плавает и BigDecimals) по-разному и преобразовать их в строки перед передачей их MessageFormat.format, (Более того, я должен помнить, чтобы делать это каждый раз.)

2 ответа

MessageFormat использует локализованное представление с тысячами разделителей, возможно, десятичную запятую и так далее. В вашем использовании он использует язык по умолчанию вашей платформы.

Что-то, что следует хранить отдельно от записи универсального программиста, valueOf/toString.

С помощью double а также precision немного оксюморон, поскольку десятичное представление является приближением суммы степеней двойки, которой является дубль внутри.

Чтобы сохранить полную информацию, вы можете хранить необработанные биты в текстовой форме, используя Double.doubleToRawLongBits и обратно longBitsToDouble,

double x = Math.PI;
String repr = String.format("%016x", Double.doubleToRawLongBits(x));
x = Double.longBitsToDouble(Long.valueOf(repr, 16));

Двойной формат в Java представлен 64 битами, для мантиссы используется 52 бита. log (252) = 15,65355977. Это означает, что точность Double составляет примерно 15-16 цифр.

Поэтому я думаю, что результат 3.141592653589793 это почти все, что вы можете получить от Double.

Другие вопросы по тегам