Я пытаюсь избавиться от ненужных символов после десятичного разделителя моего двойного значения. Я делаю его этот путь:
DecimalFormat format = new DecimalFormat("#.#####");
value = Double.valueOf(format.format(41251.50000000012343));
Но когда я выполняю этот код, он бросает:
java.lang.NumberFormatException: For input string: "41251,5"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
at java.lang.Double.valueOf(Double.java:447)
at ...
Поскольку я вижу, Double.valueOf()
работает отлично со строками как "11.1"
, но это дросселирует на строках как "11,1"
. Как я работаю вокруг этого? Есть ли более изящный путь затем что-то как
Double.valueOf(format.format(41251.50000000012343).replaceAll(",", "."));
Есть ли способ переопределить десятичное значение разделителя по умолчанию DecimalFormat
класс? Какие-либо другие мысли?
В
избавьтесь от ненужных символов после десятичного разделителя моего двойного значения
, вы действительно имеете в виду, что хотите округлить, например, пятый десятичный знак? Затем просто используйте
value = Math.round(value*1e5)/1e5;
(конечно, вы также можете Math.floor (value * 1e5) / 1e5
, если вы действительно хотите обрезать другие цифры)
Тот факт, что ваша строка форматирования использует .
в качестве десятичного разделителя, в то время как исключение жалуется на ,
указывает на проблему с языковым стандартом; то есть DecimalFormat использует другой языковой стандарт для форматирования числа, чем ожидает Double.valueOf.
В общем, вы должны создать NumberFormat
на основе определенного языкового стандарта.
Locale myLocale = ...;
NumberFormat f = NumberFormat.getInstance(myLocale);
Из JavaDocs DecimalFormat :
Чтобы получить NumberFormat для определенного языкового стандарта, включая языковой стандарт по умолчанию, вызовите один из заводских методов NumberFormat, например getInstance (). В общем, не вызывайте конструкторы DecimalFormat напрямую, поскольку методы фабрики NumberFormat могут возвращать подклассы, отличные от DecimalFormat.
Однако , как указывает BalusC , попытка отформатировать double как String, а затем разобрать String обратно на double - довольно неприятный запах кода. Я подозреваю, что вы имеете дело с проблемами, при которых вы ожидаете десятичное число с фиксированной точностью (например, денежная сумма), но сталкиваетесь с проблемами, потому что double - это число с плавающей запятой, что означает, что многие значения (например, 0.1
) не может быть точно выражен как double / float. В этом случае правильным способом обработки десятичных чисел с фиксированной точностью является использование BigDecimal
.
Проблема в том, что ваш десятичный формат преобразует ваше значение в локализованную строку. Я предполагаю, что ваш десятичный разделитель по умолчанию для вашей локали - «,
». Это часто случается с французскими регионами или другими частями мира.
По сути, вам нужно создать форматированную дату с помощью символа '.' разделитель, чтобы Double.valueOf
мог его прочитать. Как указано в комментариях, вы можете использовать тот же формат для анализа значения вместо использования Double.valueOf
.
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
symbols.setDecimalSeparator('.');
DecimalFormat format = new DecimalFormat("#.#####", symbols);
value = format.parse(format.format(41251.50000000012343));
Вы не можете изменить внутреннее представление double
/ Double
таким образом.
Если вы хотите изменить (человеческое) представление, просто оставьте его String
. Таким образом, оставьте этот Double # valueOf ()
подальше и используйте результат String
результата DecimalFormat # format ()
в своей презентации. Если вы когда-нибудь захотите провести с ним вычисления, вы всегда можете преобразовать обратно в реальный Double
, используя DecimalFormat
и Double # valueOf ()
.
Кстати, согласно вашей жалобе я пытаюсь избавиться от ненужных символов после десятичного разделителя моего двойного значения , знаете ли вы о внутреннем устройстве чисел с плавающей запятой ? Это немного пахнет тем, что вы используете неформатированные двойники на уровне представления и что вы не понимали, что со средним пользовательским интерфейсом вы можете просто представить их, используя DecimalFormat
, без необходимости конвертировать обратно в ] Двойной
.
Используйте Locale.getDefault ()
, чтобы получить десятичный разделитель вашей системы, который вы также можете установить. Вы не можете использовать разные разделители одновременно, поскольку другой обычно используется как разделитель для тысяч: 2,001,000,23 <=> 2,001,000,23
Для «,
» вместо «.
', вам придется изменить языковой стандарт.
Для количества десятичных знаков используйте setMaximumFractionDigits (int newValue)
.
Остальное см. В javadoc .
В некоторой степени связано с этим, но не является ответом на вопрос: попробуйте переключиться на BigDecimal вместо удвоений и чисел с плавающей запятой. У меня было много проблем со сравнением этих типов, и теперь я могу использовать BigDecimal.