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

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

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

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

Итак, как я могу печатать эти два раза в Java?

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

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

 232.00000000
 +0,18000000000
 +1237875192,0
 4,5800000000
 0.00000000
 1.23450000

Я хочу:

 232
 0,18
 1237875192
 4,58
 0
 1,2345

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

РЕДАКТИРОВАТЬ

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

EDIT 2

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

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

 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 

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

 new DecimalFormat("#.##").format(1.199); //"1.2" 

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

 String.format("%.2f", value) ; 

Вкратце:

Если вы хотите избавиться от конечных нhive и проблем локали, вы должны использовать:

 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 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 

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

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

Две причины:

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

Почему нет:

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

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

 0.12 12 12.144252 0 

На моей машине следующая функция примерно в 7 раз быстрее, чем функция, предоставленная ответом JasonD , поскольку она позволяет избежать String.format :

 public static String prettyPrint(double d) { int i = (int) d; return d == i ? String.valueOf(i) : String.valueOf(d); } 

Мои 2 цента:

 if(n % 1 == 0) { return String.format(Locale.US, "%.0f", n)); } else { return String.format(Locale.US, "%.1f", n)); } 

Нау, неважно.

Потеря производительности из-за манипуляции с строками равна нулю.

И вот код для обрезания конца после %f

 private static String trimTrailingZeros(String number) { if(!number.contains(".")) { return number; } return number.replaceAll("\\.?0*$", ""); } 

Обратите внимание, что String.format(format, args...) зависит от языка, потому что он форматирует с использованием локали пользователя по умолчанию, то есть, возможно, с запятыми и даже пробелами внутри, как 123 456 789 или 123 456,789 , что может быть не совсем тем, что вы ожидать.

Вы можете предпочесть использовать String.format((Locale)null, format, args...) .

Например,

  double f = 123456.789d; System.out.println(String.format(Locale.FRANCE,"%f",f)); System.out.println(String.format(Locale.GERMANY,"%f",f)); System.out.println(String.format(Locale.US,"%f",f)); 

печать

 123456,789000 123456,789000 123456.789000 

и это то, что String.format(format, args...) делает в разных странах.

EDIT Хорошо, поскольку обсуждались формальности:

  res += stripFpZeroes(String.format((Locale) null, (nDigits!=0 ? "%."+nDigits+"f" : "%f"), value)); ... protected static String stripFpZeroes(String fpnumber) { int n = fpnumber.indexOf('.'); if (n == -1) { return fpnumber; } if (n < 2) { n = 2; } String s = fpnumber; while (s.length() > n && s.endsWith("0")) { s = s.substring(0, s.length()-1); } return s; } 

Я сделал DoubleFormatter для эффективного преобразования большого количества двойных значений в красивую / презентабельную String:

 double horribleNumber = 3598945.141658554548844; DoubleFormatter df = new DoubleFormatter(4,6); //4 = MaxInteger, 6 = MaxDecimal String beautyDisplay = df.format(horribleNumber); 
  • Если целочисленная часть V имеет больше MaxInteger => дисплей V в формате ученого (1.2345e + 30), в противном случае отображается в нормальном формате 124.45678.
  • MaxDecimal определяют числа десятичных цифр (обрезание с округлением банкира)

Здесь код:

 import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Locale; import com.google.common.base.Preconditions; import com.google.common.base.Strings; /** * Convert a double to a beautiful String (US-local): * * double horribleNumber = 3598945.141658554548844; * DoubleFormatter df = new DoubleFormatter(4,6); * String beautyDisplay = df.format(horribleNumber); * String beautyLabel = df.formatHtml(horribleNumber); * * Manipulate 3 instances of NumberFormat to efficiently format a great number of double values. * (avoid to create an object NumberFormat each call of format()). * * 3 instances of NumberFormat will be reused to format a value v: * * if v < EXP_DOWN, uses nfBelow * if EXP_DOWN <= v <= EXP_UP, uses nfNormal * if EXP_UP < v, uses nfAbove * * nfBelow, nfNormal and nfAbove will be generated base on the precision_ parameter. * * @author: DUONG Phu-Hiep */ public class DoubleFormatter { private static final double EXP_DOWN = 1.e-3; private double EXP_UP; // always = 10^maxInteger private int maxInteger_; private int maxFraction_; private NumberFormat nfBelow_; private NumberFormat nfNormal_; private NumberFormat nfAbove_; private enum NumberFormatKind {Below, Normal, Above} public DoubleFormatter(int maxInteger, int maxFraction){ setPrecision(maxInteger, maxFraction); } public void setPrecision(int maxInteger, int maxFraction){ Preconditions.checkArgument(maxFraction>=0); Preconditions.checkArgument(maxInteger>0 && maxInteger<17); if (maxFraction == maxFraction_ && maxInteger_ == maxInteger) { return; } maxFraction_ = maxFraction; maxInteger_ = maxInteger; EXP_UP = Math.pow(10, maxInteger); nfBelow_ = createNumberFormat(NumberFormatKind.Below); nfNormal_ = createNumberFormat(NumberFormatKind.Normal); nfAbove_ = createNumberFormat(NumberFormatKind.Above); } private NumberFormat createNumberFormat(NumberFormatKind kind) { final String sharpByPrecision = Strings.repeat("#", maxFraction_); //if you do not use Guava library, replace with createSharp(precision); NumberFormat f = NumberFormat.getInstance(Locale.US); //Apply banker's rounding: this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations f.setRoundingMode(RoundingMode.HALF_EVEN); if (f instanceof DecimalFormat) { DecimalFormat df = (DecimalFormat) f; DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); //set group separator to space instead of comma //dfs.setGroupingSeparator(' '); //set Exponent symbol to minus 'e' instead of 'E' if (kind == NumberFormatKind.Above) { dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part } else { dfs.setExponentSeparator("e"); } df.setDecimalFormatSymbols(dfs); //use exponent format if v is out side of [EXP_DOWN,EXP_UP] if (kind == NumberFormatKind.Normal) { if (maxFraction_ == 0) { df.applyPattern("#,##0"); } else { df.applyPattern("#,##0."+sharpByPrecision); } } else { if (maxFraction_ == 0) { df.applyPattern("0E0"); } else { df.applyPattern("0."+sharpByPrecision+"E0"); } } } return f; } public String format(double v) { if (Double.isNaN(v)) { return "-"; } if (v==0) { return "0"; } final double absv = Math.abs(v); if (absvEXP_UP) { return nfAbove_.format(v); } return nfNormal_.format(v); } /** * format and higlight the important part (integer part & exponent part) */ public String formatHtml(double v) { if (Double.isNaN(v)) { return "-"; } return htmlize(format(v)); } /** * This is the base alogrithm: create a instance of NumberFormat for the value, then format it. It should * not be used to format a great numbers of value * * We will never use this methode, it is here only to understanding the Algo principal: * * format v to string. precision_ is numbers of digits after decimal. * if EXP_DOWN <= abs(v) <= EXP_UP, display the normal format: 124.45678 * otherwise display scientist format with: 1.2345e+30 * * pre-condition: precision >= 1 */ @Deprecated public String formatInefficient(double v) { final String sharpByPrecision = Strings.repeat("#", maxFraction_); //if you do not use Guava library, replace with createSharp(precision); final double absv = Math.abs(v); NumberFormat f = NumberFormat.getInstance(Locale.US); //Apply banker's rounding: this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations f.setRoundingMode(RoundingMode.HALF_EVEN); if (f instanceof DecimalFormat) { DecimalFormat df = (DecimalFormat) f; DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); //set group separator to space instead of comma dfs.setGroupingSeparator(' '); //set Exponent symbol to minus 'e' instead of 'E' if (absv>EXP_UP) { dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part } else { dfs.setExponentSeparator("e"); } df.setDecimalFormatSymbols(dfs); //use exponent format if v is out side of [EXP_DOWN,EXP_UP] if (absvEXP_UP) { df.applyPattern("0."+sharpByPrecision+"E0"); } else { df.applyPattern("#,##0."+sharpByPrecision); } } return f.format(v); } /** * Convert "3.1416e+12" to "3.1416e+12" * It is a html format of a number which highlight the integer and exponent part */ private static String htmlize(String s) { StringBuilder resu = new StringBuilder(""); int p1 = s.indexOf('.'); if (p1>0) { resu.append(s.substring(0, p1)); resu.append(""); } else { p1 = 0; } int p2 = s.lastIndexOf('e'); if (p2>0) { resu.append(s.substring(p1, p2)); resu.append(""); resu.append(s.substring(p2, s.length())); resu.append(""); } else { resu.append(s.substring(p1, s.length())); if (p1==0){ resu.append(""); } } return resu.toString(); } } . import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Locale; import com.google.common.base.Preconditions; import com.google.common.base.Strings; /** * Convert a double to a beautiful String (US-local): * * double horribleNumber = 3598945.141658554548844; * DoubleFormatter df = new DoubleFormatter(4,6); * String beautyDisplay = df.format(horribleNumber); * String beautyLabel = df.formatHtml(horribleNumber); * * Manipulate 3 instances of NumberFormat to efficiently format a great number of double values. * (avoid to create an object NumberFormat each call of format()). * * 3 instances of NumberFormat will be reused to format a value v: * * if v < EXP_DOWN, uses nfBelow * if EXP_DOWN <= v <= EXP_UP, uses nfNormal * if EXP_UP < v, uses nfAbove * * nfBelow, nfNormal and nfAbove will be generated base on the precision_ parameter. * * @author: DUONG Phu-Hiep */ public class DoubleFormatter { private static final double EXP_DOWN = 1.e-3; private double EXP_UP; // always = 10^maxInteger private int maxInteger_; private int maxFraction_; private NumberFormat nfBelow_; private NumberFormat nfNormal_; private NumberFormat nfAbove_; private enum NumberFormatKind {Below, Normal, Above} public DoubleFormatter(int maxInteger, int maxFraction){ setPrecision(maxInteger, maxFraction); } public void setPrecision(int maxInteger, int maxFraction){ Preconditions.checkArgument(maxFraction>=0); Preconditions.checkArgument(maxInteger>0 && maxInteger<17); if (maxFraction == maxFraction_ && maxInteger_ == maxInteger) { return; } maxFraction_ = maxFraction; maxInteger_ = maxInteger; EXP_UP = Math.pow(10, maxInteger); nfBelow_ = createNumberFormat(NumberFormatKind.Below); nfNormal_ = createNumberFormat(NumberFormatKind.Normal); nfAbove_ = createNumberFormat(NumberFormatKind.Above); } private NumberFormat createNumberFormat(NumberFormatKind kind) { final String sharpByPrecision = Strings.repeat("#", maxFraction_); //if you do not use Guava library, replace with createSharp(precision); NumberFormat f = NumberFormat.getInstance(Locale.US); //Apply banker's rounding: this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations f.setRoundingMode(RoundingMode.HALF_EVEN); if (f instanceof DecimalFormat) { DecimalFormat df = (DecimalFormat) f; DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); //set group separator to space instead of comma //dfs.setGroupingSeparator(' '); //set Exponent symbol to minus 'e' instead of 'E' if (kind == NumberFormatKind.Above) { dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part } else { dfs.setExponentSeparator("e"); } df.setDecimalFormatSymbols(dfs); //use exponent format if v is out side of [EXP_DOWN,EXP_UP] if (kind == NumberFormatKind.Normal) { if (maxFraction_ == 0) { df.applyPattern("#,##0"); } else { df.applyPattern("#,##0."+sharpByPrecision); } } else { if (maxFraction_ == 0) { df.applyPattern("0E0"); } else { df.applyPattern("0."+sharpByPrecision+"E0"); } } } return f; } public String format(double v) { if (Double.isNaN(v)) { return "-"; } if (v==0) { return "0"; } final double absv = Math.abs(v); if (absvEXP_UP) { return nfAbove_.format(v); } return nfNormal_.format(v); } /** * format and higlight the important part (integer part & exponent part) */ public String formatHtml(double v) { if (Double.isNaN(v)) { return "-"; } return htmlize(format(v)); } /** * This is the base alogrithm: create a instance of NumberFormat for the value, then format it. It should * not be used to format a great numbers of value * * We will never use this methode, it is here only to understanding the Algo principal: * * format v to string. precision_ is numbers of digits after decimal. * if EXP_DOWN <= abs(v) <= EXP_UP, display the normal format: 124.45678 * otherwise display scientist format with: 1.2345e+30 * * pre-condition: precision >= 1 */ @Deprecated public String formatInefficient(double v) { final String sharpByPrecision = Strings.repeat("#", maxFraction_); //if you do not use Guava library, replace with createSharp(precision); final double absv = Math.abs(v); NumberFormat f = NumberFormat.getInstance(Locale.US); //Apply banker's rounding: this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations f.setRoundingMode(RoundingMode.HALF_EVEN); if (f instanceof DecimalFormat) { DecimalFormat df = (DecimalFormat) f; DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); //set group separator to space instead of comma dfs.setGroupingSeparator(' '); //set Exponent symbol to minus 'e' instead of 'E' if (absv>EXP_UP) { dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part } else { dfs.setExponentSeparator("e"); } df.setDecimalFormatSymbols(dfs); //use exponent format if v is out side of [EXP_DOWN,EXP_UP] if (absvEXP_UP) { df.applyPattern("0."+sharpByPrecision+"E0"); } else { df.applyPattern("#,##0."+sharpByPrecision); } } return f.format(v); } /** * Convert "3.1416e+12" to "3.1416e+12" * It is a html format of a number which highlight the integer and exponent part */ private static String htmlize(String s) { StringBuilder resu = new StringBuilder(""); int p1 = s.indexOf('.'); if (p1>0) { resu.append(s.substring(0, p1)); resu.append(""); } else { p1 = 0; } int p2 = s.lastIndexOf('e'); if (p2>0) { resu.append(s.substring(p1, p2)); resu.append(""); resu.append(s.substring(p2, s.length())); resu.append(""); } else { resu.append(s.substring(p1, s.length())); if (p1==0){ resu.append(""); } } return resu.toString(); } } . import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Locale; import com.google.common.base.Preconditions; import com.google.common.base.Strings; /** * Convert a double to a beautiful String (US-local): * * double horribleNumber = 3598945.141658554548844; * DoubleFormatter df = new DoubleFormatter(4,6); * String beautyDisplay = df.format(horribleNumber); * String beautyLabel = df.formatHtml(horribleNumber); * * Manipulate 3 instances of NumberFormat to efficiently format a great number of double values. * (avoid to create an object NumberFormat each call of format()). * * 3 instances of NumberFormat will be reused to format a value v: * * if v < EXP_DOWN, uses nfBelow * if EXP_DOWN <= v <= EXP_UP, uses nfNormal * if EXP_UP < v, uses nfAbove * * nfBelow, nfNormal and nfAbove will be generated base on the precision_ parameter. * * @author: DUONG Phu-Hiep */ public class DoubleFormatter { private static final double EXP_DOWN = 1.e-3; private double EXP_UP; // always = 10^maxInteger private int maxInteger_; private int maxFraction_; private NumberFormat nfBelow_; private NumberFormat nfNormal_; private NumberFormat nfAbove_; private enum NumberFormatKind {Below, Normal, Above} public DoubleFormatter(int maxInteger, int maxFraction){ setPrecision(maxInteger, maxFraction); } public void setPrecision(int maxInteger, int maxFraction){ Preconditions.checkArgument(maxFraction>=0); Preconditions.checkArgument(maxInteger>0 && maxInteger<17); if (maxFraction == maxFraction_ && maxInteger_ == maxInteger) { return; } maxFraction_ = maxFraction; maxInteger_ = maxInteger; EXP_UP = Math.pow(10, maxInteger); nfBelow_ = createNumberFormat(NumberFormatKind.Below); nfNormal_ = createNumberFormat(NumberFormatKind.Normal); nfAbove_ = createNumberFormat(NumberFormatKind.Above); } private NumberFormat createNumberFormat(NumberFormatKind kind) { final String sharpByPrecision = Strings.repeat("#", maxFraction_); //if you do not use Guava library, replace with createSharp(precision); NumberFormat f = NumberFormat.getInstance(Locale.US); //Apply banker's rounding: this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations f.setRoundingMode(RoundingMode.HALF_EVEN); if (f instanceof DecimalFormat) { DecimalFormat df = (DecimalFormat) f; DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); //set group separator to space instead of comma //dfs.setGroupingSeparator(' '); //set Exponent symbol to minus 'e' instead of 'E' if (kind == NumberFormatKind.Above) { dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part } else { dfs.setExponentSeparator("e"); } df.setDecimalFormatSymbols(dfs); //use exponent format if v is out side of [EXP_DOWN,EXP_UP] if (kind == NumberFormatKind.Normal) { if (maxFraction_ == 0) { df.applyPattern("#,##0"); } else { df.applyPattern("#,##0."+sharpByPrecision); } } else { if (maxFraction_ == 0) { df.applyPattern("0E0"); } else { df.applyPattern("0."+sharpByPrecision+"E0"); } } } return f; } public String format(double v) { if (Double.isNaN(v)) { return "-"; } if (v==0) { return "0"; } final double absv = Math.abs(v); if (absvEXP_UP) { return nfAbove_.format(v); } return nfNormal_.format(v); } /** * format and higlight the important part (integer part & exponent part) */ public String formatHtml(double v) { if (Double.isNaN(v)) { return "-"; } return htmlize(format(v)); } /** * This is the base alogrithm: create a instance of NumberFormat for the value, then format it. It should * not be used to format a great numbers of value * * We will never use this methode, it is here only to understanding the Algo principal: * * format v to string. precision_ is numbers of digits after decimal. * if EXP_DOWN <= abs(v) <= EXP_UP, display the normal format: 124.45678 * otherwise display scientist format with: 1.2345e+30 * * pre-condition: precision >= 1 */ @Deprecated public String formatInefficient(double v) { final String sharpByPrecision = Strings.repeat("#", maxFraction_); //if you do not use Guava library, replace with createSharp(precision); final double absv = Math.abs(v); NumberFormat f = NumberFormat.getInstance(Locale.US); //Apply banker's rounding: this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations f.setRoundingMode(RoundingMode.HALF_EVEN); if (f instanceof DecimalFormat) { DecimalFormat df = (DecimalFormat) f; DecimalFormatSymbols dfs = df.getDecimalFormatSymbols(); //set group separator to space instead of comma dfs.setGroupingSeparator(' '); //set Exponent symbol to minus 'e' instead of 'E' if (absv>EXP_UP) { dfs.setExponentSeparator("e+"); //force to display the positive sign in the exponent part } else { dfs.setExponentSeparator("e"); } df.setDecimalFormatSymbols(dfs); //use exponent format if v is out side of [EXP_DOWN,EXP_UP] if (absvEXP_UP) { df.applyPattern("0."+sharpByPrecision+"E0"); } else { df.applyPattern("#,##0."+sharpByPrecision); } } return f.format(v); } /** * Convert "3.1416e+12" to "3.1416e+12" * It is a html format of a number which highlight the integer and exponent part */ private static String htmlize(String s) { StringBuilder resu = new StringBuilder(""); int p1 = s.indexOf('.'); if (p1>0) { resu.append(s.substring(0, p1)); resu.append(""); } else { p1 = 0; } int p2 = s.lastIndexOf('e'); if (p2>0) { resu.append(s.substring(p1, p2)); resu.append(""); resu.append(s.substring(p2, s.length())); resu.append(""); } else { resu.append(s.substring(p1, s.length())); if (p1==0){ resu.append(""); } } return resu.toString(); } } 

Примечание. Я использовал 2 функции из библиотеки GUAVA. Если вы не используете GUAVA, запросите код самостоятельно:

 /** * Equivalent to Strings.repeat("#", n) of the Guava library: */ private static String createSharp(int n) { StringBuilder sb = new StringBuilder(); for (int i=0;i 
 if (d == Math.floor(d)) { return String.format("%.0f", d); } else { return Double.toString(d); } 
 String s = String.valueof("your int variable"); while (g.endsWith("0") && g.contains(".")) { g = g.substring(0, g.length() - 1); if (g.endsWith(".")) { g = g.substring(0, g.length() - 1); } } 

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

  public static String removeZero(double number) { DecimalFormat format = new DecimalFormat("#.###########"); return format.format(number); } 
 new DecimalFormat("00.#").format(20.236) //out =20.2 new DecimalFormat("00.#").format(2.236) //out =02.2 
  1. 0 для минимального количества цифр
  2. Renders # цифры

Поздний ответ, но …

Вы сказали, что хотите сохранить свои номера с двойным типом . Я думаю, что это может быть причиной проблемы, потому что это заставляет вас хранить целые числа в два раза (и, следовательно, потерять исходную информацию о природе значения). Как хранить ваши номера в экземплярах classа Number (суперclass как Double, так и Integer) и полагаться на polymorphism, чтобы определить правильный формат каждого номера?

Я знаю, что это может быть неприемлемо для реорганизации целой части вашего кода из-за этого, но может привести к желаемому результату без дополнительного кода / литья / синтаксического анализа.

Пример:

 import java.util.ArrayList; import java.util.List; public class UseMixedNumbers { public static void main(String[] args) { List listNumbers = new ArrayList(); listNumbers.add(232); listNumbers.add(0.18); listNumbers.add(1237875192); listNumbers.add(4.58); listNumbers.add(0); listNumbers.add(1.2345); for (Number number : listNumbers) { System.out.println(number); } } } 

Произведет следующий вывод:

 232 0.18 1237875192 4.58 0 1.2345 

Используйте DecimalFormat и setMinimumFractionDigits(0)

Вот два способа добиться этого. Во-первых, более короткий (и, вероятно, лучший) способ:

 public static String formatFloatToString(final float f) { final int i=(int)f; if(f==i) return Integer.toString(i); return Float.toString(f); } 

И вот длинный и, вероятно, худший способ:

 public static String formatFloatToString(final float f) { final String s=Float.toString(f); int dotPos=-1; for(int i=0;i 
 public static String fmt(double d) { String val = Double.toString(d); String[] valArray = val.split("\\."); long valLong = 0; if(valArray.length == 2){ valLong = Long.parseLong(valArray[1]); } if (valLong == 0) return String.format("%d", (long) d); else return String.format("%s", d); } 

Мне пришлось использовать эту причину. d == (long)d давал мне нарушение в отчете о сонаре

Вот что я придумал:

  private static String format(final double dbl) { return dbl % 1 != 0 ? String.valueOf(dbl) : String.valueOf((int) dbl); } 

Простой один вкладыш, только отбрасывает int, если действительно нужно

Вот ответ, который на самом деле работает (сочетание разных ответов здесь)

 public static String removeTrailingZeros(double f) { if(f == (int)f) { return String.format("%d", (int)f); } return String.format("%f", f).replaceAll("0*$", ""); } 

Я знаю, что это действительно старая нить .. Но я думаю, что лучший способ сделать это:

 public class Test { public static void main(String args[]){ System.out.println(String.format("%s something",new Double(3.456))); System.out.println(String.format("%s something",new Double(3.456234523452))); System.out.println(String.format("%s something",new Double(3.45))); System.out.println(String.format("%s something",new Double(3))); } } 

Вывод:

 3.456 something 3.456234523452 something 3.45 something 3.0 something 

Единственная проблема – последняя, ​​где .0 не удаляется. Но если вы можете жить с этим, тогда это лучше всего работает. % .2f будет округлять его до двух последних десятичных цифр. Так будет DecimalFormat. Если вам нужны все десятичные разряды, но не конечные нули, тогда это лучше всего работает.

 String s = "1.210000"; while (s.endsWith("0")){ s = (s.substring(0, s.length() - 1)); } 

Это приведет к тому, что строка вернет хвост 0-s.

  • Арифметика с плавающей точкой не дает точных результатов
  • Типы с плавающей запятой с фиксированным размером
  • Должен ли я использовать double или float?
  • Как сравнить два числа с плавающей запятой в Bash?
  • Как получить знак, мантисса и показатель числа с плавающей запятой
  • сравнение значений float / double с использованием оператора ==
  • Приведение float в int (побитовое) в C
  • Когда следует использовать ключевое слово "strictfp" в java?
  • Разница между десятичной, плавающей и двойной в .NET?
  • Точность с плавающей запятой C ++
  • Почему изменение 0.1f to 0 замедляет производительность на 10x?
  • Давайте будем гением компьютера.