64-битный дубль может точно представлять целое число +/- 2 53
Учитывая этот факт, я решил использовать двойной тип как один тип для всех моих типов, так как мое самое большое целое число - 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
Конечно, я могу написать функцию для обрезки этих нулей, но это большая потеря производительности из-за манипуляций со строками. Могу ли я сделать лучше с другим форматом кода?
РЕДАКТИРОВАТЬ
Ответы Тома Э. и Джереми С. неприемлемы, поскольку они оба произвольно округляют до 2 десятичных знаков. Пожалуйста, поймите проблему, прежде чем ответить.
РЕДАКТИРОВАТЬ 2
Обратите внимание, что String.format(format, args...)
это зависит от локали (см. Ответы ниже).
System.out.println("YOUR STRING" + YOUR_DOUBLE_VARIABLE);
Ответы:
Если идея состоит в том, чтобы напечатать целые числа, хранящиеся в виде двойных чисел, как если бы они были целыми числами, а в противном случае выведите двойные числа с минимально необходимой точностью:
Производит:
И не полагается на манипуляции со строками.
источник
double
большим, чем максимальноеint
значение. Даже сlong
этим все равно не получится для огромного количества. Кроме того, он вернет String в экспоненциальной форме, например, «1.0E10», для больших значений, что, вероятно, не то, что хочет запрашивающий. Используйте%f
вместо%s
второй строки формата, чтобы исправить это.%f
. Ответ зависит от описанной ситуации и желаемого результата. ОП предположил, что их максимальным значением было 32-битное целое число без знака, которое, как я понял,int
было приемлемым (без знака на самом деле не существует в Java, и ни один пример не был проблематичным), но его изменениеint
наlong
тривиальное исправление, если ситуация отличается.String.format("%s",d)
??? Поговорим о ненужных накладных расходах. ИспользованиеDouble.toString(d)
. То же самое для другого:Long.toString((long)d)
.%s
не работает с локалями. В немецком языке мы используем «,» вместо «.» в десятичных числах. В то время какString.format(Locale.GERMAN, "%f", 1.5)
возвращает «1,500000»,String.format(Locale.GERMAN, "%s", 1.5)
возвращает «1,5» - с «.», Что является ложным в немецком языке. Есть ли зависящая от локали версия "% s"?Как указано в комментариях, это не правильный ответ на исходный вопрос.
Тем не менее, это очень полезный способ форматирования чисел без лишних конечных нулей.
источник
источник
Короче говоря:
Если вы хотите избавиться от конечных нулей и проблем локали, то вам следует использовать:
Объяснение:
Почему другие ответы меня не устраивают:
Double.toString()
илиSystem.out.println
илиFloatingDecimal.toJavaFormatString
использует научные записи, если double меньше 10 ^ -3 или больше или равно 10 ^ 7при использовании
%f
десятичная точность по умолчанию равна 6, в противном случае вы можете жестко закодировать ее, но это приведет к добавлению дополнительных нулей, если у вас меньше десятичных дробей. Пример :используя
setMaximumFractionDigits(0);
или%.0f
вы удаляете любую десятичную точность, которая подходит для целых / длинных, но не для двойнойиспользуя DecimalFormat, вы локально зависимы. Во французском языке десятичный разделитель - это запятая, а не точка:
Использование английского языка гарантирует, что вы получите точку для десятичного разделителя, где бы ни была запущена ваша программа
Зачем использовать 340 тогда для
setMaximumFractionDigits
?Две причины:
setMaximumFractionDigits
принимает целое число, но его реализация имеет максимально допустимые цифры,DecimalFormat.DOUBLE_FRACTION_DIGITS
равные 340Double.MIN_VALUE = 4.9E-324
так что с 340 цифрами вы точно не округлите свою двойную и потерянную точностьисточник
0
вместо#.
DecimalFormat.DOUBLE_FRACTION_DIGITS
но используете значение 340, для которого вы затем предоставляете комментарий, чтобы показать, что оно равноDecimalFormat.DOUBLE_FRACTION_DIGITS
. Почему бы просто не использовать константу ???Почему бы нет:
Это должно работать с экстремальными значениями, поддерживаемыми Double. Урожайность:
источник
"%s"
основном звонки,d.toString()
но это не работает сint
или еслиd==null
!На моей машине следующая функция примерно в 7 раз быстрее, чем функция, предоставленная ответом JasonD , поскольку она избегает
String.format
:источник
Мои 2 цента:
источник
return String.format(Locale.US, (n % 1 == 0 ? "%.0f" : "%.1f"), n);
.Нет, неважно.
Потеря производительности из-за манипуляций со строками равна нулю.
И вот код, чтобы обрезать конец после
%f
источник
Используйте
DecimalFormat
иsetMinimumFractionDigits(0)
источник
setMaximumFractionDigits(2)
иsetGroupingUsed(false)
(OP не упоминает об этом, но из примера кажется, что это требуется). Кроме того, небольшой тестовый пример не повредит, поскольку в этом случае он тривиален. Тем не менее, поскольку я думаю, что это самое простое решение, upvote - это upvote :)источник
Обратите внимание, что
String.format(format, args...)
это зависит от локали, потому что форматируется с использованием локали пользователя по умолчанию, то есть, вероятно, с запятыми и даже пробелами внутри, например 123 456 789 или 123 456,789 , что может быть не совсем то, что вы ожидаете.Вы можете предпочесть использовать
String.format((Locale)null, format, args...)
.Например,
печать
и это то, что будет
String.format(format, args...)
делать в разных странах.РЕДАКТИРОВАТЬ ОК, так как было обсуждение формальностей:
источник
Я сделал
DoubleFormatter
для эффективного преобразования большого числа двойных значений в красивую / презентабельную строку:Вот код:
Примечание: я использовал 2 функции из библиотеки GUAVA. Если вы не используете GUAVA, закодируйте его самостоятельно:
источник
Это хорошо выполнит работу, я знаю, что тема старая, но я боролся с той же проблемой, пока не пришел к этому. Я надеюсь, что кто-то найдет это полезным.
источник
источник
источник
Поздний ответ, но ...
Вы сказали, что решили хранить свои номера с двойным типом . Я думаю, что это может быть корнем проблемы, потому что это заставляет вас хранить целые числа в двойных числах (и, следовательно, терять первоначальную информацию о природе значения). Как насчет хранения ваших номеров в экземплярах номера класса (суперкласса Double и Integer) и полагаться на полиморфизм для определения правильного формата каждого числа?
Я знаю, что это может быть неприемлемо для рефакторинга целой части вашего кода из-за этого, но это может привести к желаемому результату без дополнительного кода / приведения / разбора.
Пример:
Будет производить следующий вывод:
источник
Вот что я придумал:
Простой один лайнер, только бросает к int, если действительно нужно
источник
Форматирование цены с группировкой, округлением, без лишних нулей (в двойном размере).
Правила:
2.0000 = 2; 1.0100000 = 1.01
)2.010 = 2.01; 0.20 = 0.2
)1.994 = 1.99; 1.995 = 2; 1.006 = 1.01; 0.0006 -> 0
)0
(null/-0 = 0
)$
(= $56/-$56
)101101.02 = $101,101.02
)Больше примеров:
Написанный на Kotlin как забавное расширение Double (причина, используемая в Android), но может быть легко преобразован в Java, потому что были использованы классы Java.
Как пользоваться:
О десятичном формате : https://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html.
источник
Я должен был использовать эту причину,
d == (long)d
дала мне нарушение в отчете сонараисточник
это результат некоторых тестов:
источник
Вот два способа добиться этого. Во-первых, более короткий (и, вероятно, лучший) путь:
А вот более длинный и, вероятно, худший путь:
источник
Для Kotlin вы можете использовать расширение как:
источник
Вот еще один ответ, который имеет возможность добавить десятичную ТОЛЬКО ЕСЛИ десятичная дробь не была равна нулю.
источник
Вот ответ, который действительно работает (комбинация различных ответов здесь)
источник
Я знаю, что это действительно старая тема. Но я думаю, что лучший способ сделать это, как показано ниже:
Вывод:
Единственная проблема - последняя, где .0 не удаляется. Но если вы можете жить с этим, то это работает лучше всего. % .2f округляет его до 2 последних десятичных цифр. Так будет и с DecimalFormat. Если вам нужны все десятичные разряды, но не конечные нули, то это работает лучше всего.
источник
System.out.println(new java.text.DecimalFormat("#.##").format(1.0005));
будет напечатано1
Это заставит строку отбросить хвостовые 0-s.
источник