Как красиво форматировать плавающие числа в String без ненужного десятичного числа 0?
64-битный двойной может представлять целое число +/- 2 53 точно
Учитывая этот факт, я предпочитаю использовать двойной тип как один тип для всех моих типов, так как мое наибольшее целое число равно 32-разрядному без знака.
Но теперь мне приходится печатать эти псевдо-целые числа, но проблема в том, что они также смешиваются с фактическими удвоениями.
- Почему 24.0000 не равно 24.0000 в MATLAB?
- Вставить в int vs floor
- Сравнение числа с плавающей точкой с нолем
- Могут ли какие-либо процессоры реального мира не использовать IEEE 754?
- Формат Float до n знаков после запятой
Итак, как я могу печатать эти два раза в 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...)
зависит от языка (см. Ответы ниже).
- Как вы печатаете EXACT значение числа с плавающей запятой?
- Как эффективно выполнять преобразования double / int64 с помощью SSE / AVX?
- В MATLAB переменные ДЕЙСТВИТЕЛЬНО двойной точности по умолчанию?
- Float / double precision в режимах отладки / выпуска
- Почему это вычитание не равно нулю?
- Почему «f» требуется при объявлении float?
- Получение фактической ширины элемента с плавающей запятой
- Преобразование float в строку
Если идея состоит в том, чтобы печатать целые числа, хранящиеся как удвоенные, как если бы они были целыми числами, и в противном случае печатать удвоения с минимально необходимой точностью:
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 ^ 7double 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 (absv
.EXP_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 (absv EXP_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 (absv
.EXP_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 (absv EXP_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 (absv
EXP_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 (absv EXP_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
- 0 для минимального количества цифр
- 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.