Вопрос-ответ

How to nicely format floating numbers to string without unnecessary decimal 0's

Как красиво отформатировать числа с плавающей запятой в строку без ненужных десятичных 0

64-битный double может точно представлять целое число + /- 253.

Учитывая этот факт, я выбираю использовать тип double в качестве единого типа для всех моих типов, поскольку мое наибольшее целое число - это 32-разрядное число без знака.

Но теперь я должен напечатать эти псевдо-целые числа, но проблема в том, что они также смешаны с фактическими двойными числами.

Итак, как мне красиво напечатать эти двойные значения в Java?

Я пробовал String.format("%f", value), что близко, за исключением того, что я получаю много завершающих нулей для небольших значений.

Вот пример вывода из %f

232.00000000
0.18000000000
1237875192.0
4.5800000000
0.00000000
1.23450000

Чего я хочу, так это:

232
0.18
1237875192
4.58
0
1.2345

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


Ответы Тома Э. и Джереми С. неприемлемы, поскольку оба они произвольно округляются до двух знаков после запятой. Пожалуйста, поймите проблему, прежде чем отвечать.


Пожалуйста, обратите внимание, что String.format(format, args...) это зависит от локали (см. Ответы ниже).

Переведено автоматически
Ответ 1

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

public static String fmt(double d)
{
if(d == (long) d)
return String.format("%d",(long)d);
else
return String.format("%s",d);
}

Производит:

232
0.18
1237875192
4.58
0
1.2345

И не полагается на манипулирование строками.

Ответ 2
String.format("%.2f", value);
Ответ 3

Вкратце:

Если вы хотите избавиться от завершающих нулей и проблем с локализацией, то вам следует использовать:

double myValue = 0.00000021d;

DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); //340 = DecimalFormat.DOUBLE_FRACTION_DIGITS

System.out.println(df.format(myValue)); //output: 0.00000021

Объяснение:

Почему другие ответы меня не устроили:


  • Double.toString() или System.out.println или FloatingDecimal.toJavaFormatString использует научные обозначения, если double меньше 10 ^ -3 или больше или равно 10 ^ 7


     double myValue = 0.00000021d;
    String.format("%s", myvalue); //output: 2.1E-7


  • при использовании %f десятичная точность по умолчанию равна 6, в противном случае вы можете запрограммировать ее жестко, но это приведет к добавлению дополнительных нулей, если у вас меньше десятичных знаков. Пример:


     double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000


  • используя setMaximumFractionDigits(0); или %.0f, вы удаляете любую десятичную точность, что подходит для целых чисел / длин, но не для double


     double myValue = 0.00000021d;
    System.out.println(String.format("%.0f", myvalue)); // Output: 0
    DecimalFormat df = new DecimalFormat("0");
    System.out.println(df.format(myValue)); // Output: 0


  • используя DecimalFormat, вы зависите от локального интерфейса. Во французском языке десятичным разделителем является запятая, а не точка:


     double myValue = 0.00000021d;
    DecimalFormat df = new DecimalFormat("0");
    df.setMaximumFractionDigits(340);
    System.out.println(df.format(myvalue)); // Output: 0,00000021

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



Зачем тогда использовать 340 для setMaximumFractionDigits?

Две причины:


  • setMaximumFractionDigits принимает целое число, но его реализация имеет максимально допустимые цифры из DecimalFormat.DOUBLE_FRACTION_DIGITS, которые равны 340

  • Double.MIN_VALUE = 4.9E-324 таким образом, с 340 цифрами вы точно не будете округлять вдвое и терять точность

Ответ 4

Использование:

if (d % 1.0 != 0)
return String.format("%s", d);
else
return String.format("%.0f", d);

Это должно работать с экстремальными значениями, поддерживаемыми Double . Это дает:

0.12
12
12.144252
0
java string