2014-09-23 1 views
5

Если я отформатирую двойной метод, используя метод toString, я получу полную точность двойника. Так, например (с использованием Scala синтаксис):Как я могу выводить локализованные значения с плавающей запятой Java с полной точностью?

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

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

3.141592653589793 

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

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

(AnyRef является Скала типа, который эквивалентен 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, number}», то получаю смехотворное значение 10,000,000,000,000,000,000,000,000,000,000,000,000.

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

UPDATE:

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

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

'BigDecimal' может быть? –

+0

Мне не нужен «BigDecimal» - обычный двойной вариант подходит для моих целей. Преобразование в BigDecimal столь же громоздко для меня, как преобразование в строку. –

+0

На самом деле, я просто попытался преобразовать 'PI' в BigDecimal и вывести ... ... и получил« 3.142 »в результате, так что это тоже не сработает. ;-) –

ответ

-1

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

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

+0

Вопрос был: _ Есть ли строка формата формата, которая выводит полную точность двойника? _ Это не вопрос повышения точности значения с плавающей запятой, а вопрос о выводе значения, хранящегося в двойном с максимальной точностью. Я указал, что вы получаете полную точность, если сначала конвертируете двойное значение в строку, но, похоже, нет способа сделать это с помощью 'MessageFormat'. –

+0

@MikeAllen извините, я пропустил точку вашего вопроса. Итак, вернемся к теме. Похоже, что нет простого и понятного способа сделать DF-формат MessageFormat так, как вы хотите. Я могу просто указать, что предоставление пользовательского шаблона, такого как «#. ##########################», будет работать (как вы упомянули), но оно не работает Фактически требуется знание точности Double. Вы можете указать любое количество цифр после точки, и оно будет работать. Возможно, вы можете рассмотреть возможность форматирования постоянной с некоторыми дополнительными цифрами в хвосте и использовать ее там, где это необходимо. – Aivean

+0

Спасибо за ответ. Проблема, с которой я борюсь, заключается в том, что пользовательские форматы, так или иначе, урезают точность/точность выводимого значения. Если бы я знал, что величина двойника была, скажем, в диапазоне 1-10, то формат, который вы указали, будет прекрасным. Но что, если значение было 1.2345E-37? Ваш формат будет выдавать 0,000000000000000 - так что я бы потерял * всю точность! –

0

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

Что-то одно должно держаться отдельно от нотации универсального программиста, valueOf/toString.

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

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

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

Спасибо за ваши комментарии. Я понимаю, как дубликаты хранятся внутри, и я понимаю, что нет 100% точного способа представления этого значения в виде десятичной строки. Тем не менее, я надеюсь, что вы согласитесь, что 'toString' делает довольно хорошую работу по выводу полного содержимого двойного значения в удобочитаемую форму. Мне просто нужна такая же верность при использовании 'MessageFormat.format' с двойным. Ваше предложение сохраняет точность, но большинство людей будет пытаться понять представленную стоимость. –

+0

Я так боялся. Когда-то был вопрос SO о максимальном количестве мест в двойнике, как этот [how-many-decimal-places-in-a-double-java]. (Http://stackoverflow.com/questions/3334168/ как-много-десятичные-места-в-двойной Java). –

Смежные вопросы