Как округлить число до n десятичных знаков в Java

То, что я хотел бы, это метод преобразования double в строку, которая округляет, используя метод полураспада – то есть, если десятичное число округляется до 5, оно всегда округляется до предыдущего числа. Это стандартный метод округления большинства людей в большинстве ситуаций.

Я также хотел бы отображать только значимые цифры, т. Е. Не должно быть никаких конечных нhive.

Я знаю, что один из способов сделать это – использовать метод String.format :

 String.format("%.5g%n", 0.912385); 

возвращает:

 0.91239 

что отлично, однако он всегда отображает числа с 5 знаками после запятой, даже если они не значительны:

 String.format("%.5g%n", 0.912300); 

возвращает:

 0.91230 

Другой метод – использовать DecimalFormatter :

 DecimalFormat df = new DecimalFormat("#.#####"); df.format(0.912385); 

возвращает:

 0.91238 

Однако, как вы видите, это использует округлые округления. То есть он округляется, если предыдущая цифра четная. Я бы хотел:

 0.912385 -> 0.91239 0.912300 -> 0.9123 

Каков наилучший способ достичь этого в Java?

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

    Пример:

     DecimalFormat df = new DecimalFormat("#.####"); df.setRoundingMode(RoundingMode.CEILING); for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) { Double d = n.doubleValue(); System.out.println(df.format(d)); } 

    дает выход:

     12 123.1235 0.23 0.1 2341234.2125 

    Предполагая, что value равно double , вы можете сделать следующее:

     (double)Math.round(value * 100000d) / 100000d 

    Это для 5 цифр точности. Число нhive указывает количество десятичных знаков.

     new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP); 

    вы получите BigDecimal . Чтобы получить строку из нее, просто вызовите метод BigDecimal toString или метод toPlainString для Java 5+ для строки простого формата.

    Пример программы:

     package trials; import java.math.BigDecimal; public class Trials { public static void main(String[] args) { int yourScale = 10; System.out.println(BigDecimal.valueOf(0.42344534534553453453-0.42324534524553453453).setScale(yourScale, BigDecimal.ROUND_HALF_UP)); } 

    Вы также можете использовать

     DecimalFormat df = new DecimalFormat("#.00000"); df.format(0.912385); 

    чтобы убедиться, что у вас есть задние 0.

    Как отмечали некоторые другие, правильным ответом является использование DecimalFormat или BigDecimal . Плавающая точка не имеет десятичных знаков, поэтому вы не можете округлить / усечь до определенного числа из них в первую очередь. Вы должны работать в десятичной системе, и это то, что делают эти два classа.

    Я отправляю следующий код в качестве контр-примера для всех ответов в этом streamе и даже по всему StackOverflow (и в другом месте), которые рекомендуют умножение с последующим усечением, за которым следует разделение. На адвокатов этой методики должно объясняться, почему следующий код производит неправильный вывод в более чем 92% случаев.

     public class RoundingCounterExample { static float roundOff(float x, int position) { float a = x; double temp = Math.pow(10.0, position); a *= temp; a = Math.round(a); return (a / (float)temp); } public static void main(String[] args) { float a = roundOff(0.0009434f,3); System.out.println("a="+a+" (a % .001)="+(a % 0.001)); int count = 0, errors = 0; for (double x = 0.0; x < 1; x += 0.0001) { count++; double d = x; int scale = 2; double factor = Math.pow(10, scale); d = Math.round(d * factor) / factor; if ((d % 0.01) != 0.0) { System.out.println(d + " " + (d % 0.01)); errors++; } } System.out.println(count + " trials " + errors + " errors"); } } 

    Вывод этой программы:

     10001 trials 9251 errors 

    EDIT: Чтобы рассмотреть некоторые комментарии ниже, я new MathContext(16) часть тестового цикла с помощью BigDecimal и new MathContext(16) для работы модуля следующим образом:

     public static void main(String[] args) { int count = 0, errors = 0; int scale = 2; double factor = Math.pow(10, scale); MathContext mc = new MathContext(16, RoundingMode.DOWN); for (double x = 0.0; x < 1; x += 0.0001) { count++; double d = x; d = Math.round(d * factor) / factor; BigDecimal bd = new BigDecimal(d, mc); bd = bd.remainder(new BigDecimal("0.01"), mc); if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0) { System.out.println(d + " " + bd); errors++; } } System.out.println(count + " trials " + errors + " errors"); } 

    Результат:

     10001 trials 4401 errors 

    Предположим, что у вас есть

     double d = 9232.129394d; 

    вы можете использовать BigDecimal

     BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN); d = bd.doubleValue(); 

    или без BigDecimal

     d = Math.round(d*100)/100.0d; 

    с обоими решениями d == 9232.13

    Вы можете использовать class DecimalFormat.

     double d = 3.76628729; DecimalFormat newFormat = new DecimalFormat("#.##"); double twoDecimal = Double.valueOf(newFormat.format(d)); 

    Java Real-How-to представляет собой решение, которое также совместимо для версий до версии Java 1.6.

     BigDecimal bd = new BigDecimal(Double.toString(d)); bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP); return bd.doubleValue(); 
     double myNum = .912385; int precision = 10000; //keep 4 digits myNum= Math.floor(myNum * precision +.5)/precision; 

    @Milhous: десятичный формат округления превосходный:

    Вы также можете использовать

     DecimalFormat df = new DecimalFormat("#.00000"); df.format(0.912385); 

    чтобы убедиться, что у вас есть задние 0.

    Я бы добавил, что этот метод очень хорош в обеспечении реального числового, округляющего механизма – не только визуально, но и при обработке.

    Гипотетическая: вам нужно внедрить механизм округления в программу GUI. Чтобы изменить точность / точность результата, просто измените формат каретки (т. Е. В скобках). Так что:

     DecimalFormat df = new DecimalFormat("#0.######"); df.format(0.912385); 

    вернется как результат: 0.912385

     DecimalFormat df = new DecimalFormat("#0.#####"); df.format(0.912385); 

    вернется как результат: 0.91239

     DecimalFormat df = new DecimalFormat("#0.####"); df.format(0.912385); 

    вернется как результат: 0.9124

    [EDIT: также, если формат каретки выглядит так («# 0. ############»), и вы вводите десятичное число, например, 3.1415926, для аргументации, DecimalFormat не производит никакого мусора ( например, заканчивая нулями) и вернется: 3.1415926 .. если вы так склонны. Конечно, это немного многословно для нравов некоторых разработчиков, но эй, у него низкий объем памяти во время обработки и его очень легко реализовать.]

    Таким образом, красота DecimalFormat заключается в том, что она одновременно обрабатывает внешний вид строки, а также уровень точности округления. Эрго: вы получаете два преимущества по цене одной реализации кода. 😉

    Вы можете использовать следующий метод утилиты –

     public static double round(double valueToRound, int numberOfDecimalPlaces) { double multipicationFactor = Math.pow(10, numberOfDecimalPlaces); double interestedInZeroDPs = valueToRound * multipicationFactor; return Math.round(interestedInZeroDPs) / multipicationFactor; } 

    Вот краткое изложение того, что вы можете использовать, если хотите, чтобы результат был как String:

    1. DecimalFormat # setRoundingMode () :

       DecimalFormat df = new DecimalFormat("#.#####"); df.setRoundingMode(RoundingMode.HALF_UP); String str1 = df.format(0.912385)); // 0.91239 
    2. BigDecimal # setScale ()

       String str2 = new BigDecimal(0.912385) .setScale(5, BigDecimal.ROUND_HALF_UP) .toString(); 

    Вот предложение о том, какие библиотеки вы можете использовать, если хотите получить double результат. Я бы не рекомендовал его для преобразования строк, хотя, поскольку double не может точно представлять то, что вы хотите (см., Например, здесь ):

    1. Точность из Apache Commons Math

       double rounded = Precision.round(0.912385, 5, BigDecimal.ROUND_HALF_UP); 
    2. Функции от Colt

       double rounded = Functions.round(0.00001).apply(0.912385) 
    3. Утилиты из Weka

       double rounded = Utils.roundDouble(0.912385, 5) 

    Кратким решением:

      public static double round(double value, int precision) { int scale = (int) Math.pow(10, precision); return (double) Math.round(value * scale) / scale; } 

    См. Также https://stackoverflow.com/a/22186845/212950. Благодаря jpdymond для этого.

    Вы можете использовать BigDecimal

     BigDecimal value = new BigDecimal("2.3"); value = value.setScale(0, RoundingMode.UP); BigDecimal value1 = new BigDecimal("-2.3"); value1 = value1.setScale(0, RoundingMode.UP); System.out.println(value + "n" + value1); 

    См .: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/

    Попробуйте это: org.apache.commons.math3.util.Precision.round (double x, int scale)

    См .: http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/Precision.html.

    Домашняя страница библиотеки математики Apache Commons: http://commons.apache.org/proper/commons-math/index.html

    Внутренняя реализация этого метода:

     public static double round(double x, int scale) { return round(x, scale, BigDecimal.ROUND_HALF_UP); } public static double round(double x, int scale, int roundingMethod) { try { return (new BigDecimal (Double.toString(x)) .setScale(scale, roundingMethod)) .doubleValue(); } catch (NumberFormatException ex) { if (Double.isInfinite(x)) { return x; } else { return Double.NaN; } } } 

    Поскольку я не нашел полного ответа на эту тему, я собрал class, который должен справиться с этим должным образом, с поддержкой:

    • Форматирование : легко форматировать двойную строку с определенным количеством знаков после запятой
    • Анализ : проанализируйте отформатированное значение в два раза
    • Язык : формат и синтаксический анализ с использованием стандартного языкового стандарта
    • Экспоненциальная нотация : начните использовать экспоненциальную нотацию после определенного порога

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

    (Для этого примера я использую пользовательский язык)

     public static final int DECIMAL_PLACES = 2; NumberFormatter formatter = new NumberFormatter(DECIMAL_PLACES); String value = formatter.format(9.319); // "9,32" String value2 = formatter.format(0.0000005); // "5,00E-7" String value3 = formatter.format(1324134123); // "1,32E9" double parsedValue1 = formatter.parse("0,4E-2", 0); // 0.004 double parsedValue2 = formatter.parse("0,002", 0); // 0.002 double parsedValue3 = formatter.parse("3423,12345", 0); // 3423.12345 

    Вот class :

     import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.ParseException; import java.util.Locale; public class NumberFormatter { private static final String SYMBOL_INFINITE = "\u221e"; private static final char SYMBOL_MINUS = '-'; private static final char SYMBOL_ZERO = '0'; private static final int DECIMAL_LEADING_GROUPS = 10; private static final int EXPONENTIAL_INT_THRESHOLD = 1000000000; // After this value switch to exponential notation private static final double EXPONENTIAL_DEC_THRESHOLD = 0.0001; // Below this value switch to exponential notation private DecimalFormat decimalFormat; private DecimalFormat decimalFormatLong; private DecimalFormat exponentialFormat; private char groupSeparator; public NumberFormatter(int decimalPlaces) { configureDecimalPlaces(decimalPlaces); } public void configureDecimalPlaces(int decimalPlaces) { if (decimalPlaces <= 0) { throw new IllegalArgumentException("Invalid decimal places"); } DecimalFormatSymbols separators = new DecimalFormatSymbols(Locale.getDefault()); separators.setMinusSign(SYMBOL_MINUS); separators.setZeroDigit(SYMBOL_ZERO); groupSeparator = separators.getGroupingSeparator(); StringBuilder decimal = new StringBuilder(); StringBuilder exponential = new StringBuilder("0."); for (int i = 0; i < DECIMAL_LEADING_GROUPS; i++) { decimal.append("###").append(i == DECIMAL_LEADING_GROUPS - 1 ? "." : ","); } for (int i = 0; i < decimalPlaces; i++) { decimal.append("#"); exponential.append("0"); } exponential.append("E0"); decimalFormat = new DecimalFormat(decimal.toString(), separators); decimalFormatLong = new DecimalFormat(decimal.append("####").toString(), separators); exponentialFormat = new DecimalFormat(exponential.toString(), separators); decimalFormat.setRoundingMode(RoundingMode.HALF_UP); decimalFormatLong.setRoundingMode(RoundingMode.HALF_UP); exponentialFormat.setRoundingMode(RoundingMode.HALF_UP); } public String format(double value) { String result; if (Double.isNaN(value)) { result = ""; } else if (Double.isInfinite(value)) { result = String.valueOf(SYMBOL_INFINITE); } else { double absValue = Math.abs(value); if (absValue >= 1) { if (absValue >= EXPONENTIAL_INT_THRESHOLD) { value = Math.floor(value); result = exponentialFormat.format(value); } else { result = decimalFormat.format(value); } } else if (absValue < 1 && absValue > 0) { if (absValue >= EXPONENTIAL_DEC_THRESHOLD) { result = decimalFormat.format(value); if (result.equalsIgnoreCase("0")) { result = decimalFormatLong.format(value); } } else { result = exponentialFormat.format(value); } } else { result = "0"; } } return result; } public String formatWithoutGroupSeparators(double value) { return removeGroupSeparators(format(value)); } public double parse(String value, double defValue) { try { return decimalFormat.parse(value).doubleValue(); } catch (ParseException e) { e.printStackTrace(); } return defValue; } private String removeGroupSeparators(String number) { return number.replace(String.valueOf(groupSeparator), ""); } } 

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

     private String withNoTrailingZeros(final double value, final int nrOfDecimals) { return new BigDecimal(String.valueOf(value)).setScale(nrOfDecimals, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString(); } 

    возвращает String с требуемым выходом.

    Если вам действительно нужны десятичные числа для вычисления (и не только для вывода), не используйте бинарный формат с плавающей запятой, такой как double.

     Use BigDecimal or any other decimal-based format. 

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

    Фактически, я недавно использовал parsed-to-Long для получения точных представлений (в отличие от результатов hex) в графическом интерфейсе для чисел, больших как ################# ############### символов (в качестве примера).

    Если вы используете DecimalFormat для преобразования double в String , это очень просто:

     DecimalFormat formatter = new DecimalFormat("0.0##"); formatter.setRoundingMode(RoundingMode.HALF_UP); double num = 1.234567; return formatter.format(num); 

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

    В приведенном ниже fragmentе кода показано, как отображать n цифр. Фокус в том, чтобы установить переменную pp в 1, за которой следуют n нhive. В приведенном ниже примере переменное значение pp имеет 5 нhive, поэтому будет отображаться 5 цифр.

     double pp = 10000; double myVal = 22.268699999999967; String needVal = "22.2687"; double i = (5.0/pp); String format = "%10.4f"; String getVal = String.format(format,(Math.round((myVal +i)*pp)/pp)-i).trim(); 

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

    Как округлить число в Java

    Наиболее распространенным случаем является использование Math.round() .

     Math.round(3.7) // 4 

    Числа округлены до ближайшего целого числа. Значение .5 округляется. Если вам нужно другое поведение округления, то вы можете использовать одну из других математических функций. См. Сравнение ниже.

    круглый

    Как указано выше, это округляет до ближайшего целого числа. .5 десятичных знаков округляют вверх. Этот метод возвращает int .

     Math.round(3.0); // 3 Math.round(3.1); // 3 Math.round(3.5); // 4 Math.round(3.9); // 4 Math.round(-3.0); // -3 Math.round(-3.1); // -3 Math.round(-3.5); // -3 *** careful here *** Math.round(-3.9); // -4 

    перекрывать

    Любое десятичное значение округляется до следующего целого числа. Это идет к потолку . Этот метод возвращает double .

     Math.ceil(3.0); // 3.0 Math.ceil(3.1); // 4.0 Math.ceil(3.5); // 4.0 Math.ceil(3.9); // 4.0 Math.ceil(-3.0); // -3.0 Math.ceil(-3.1); // -3.0 Math.ceil(-3.5); // -3.0 Math.ceil(-3.9); // -3.0 

    пол

    Любое десятичное значение округляется до следующего целого. Этот метод возвращает double .

     Math.floor(3.0); // 3.0 Math.floor(3.1); // 3.0 Math.floor(3.5); // 3.0 Math.floor(3.9); // 3.0 Math.floor(-3.0); // -3.0 Math.floor(-3.1); // -4.0 Math.floor(-3.5); // -4.0 Math.floor(-3.9); // -4.0 

    ечать

    Это похоже на округление в десятичных значениях, округленных до ближайшего целого числа. Однако, в отличие от round , .5 значений округляют до четного целого. Этот метод возвращает double .

     Math.rint(3.0); // 3.0 Math.rint(3.1); // 3.0 Math.rint(3.5); // 4.0 *** Math.rint(3.9); // 4.0 Math.rint(4.5); // 4.0 *** Math.rint(5.5); // 6.0 *** Math.rint(-3.0); // -3.0 Math.rint(-3.1); // -3.0 Math.rint(-3.5); // -4.0 *** Math.rint(-3.9); // -4.0 Math.rint(-4.5); // -4.0 *** Math.rint(-5.5); // -6.0 *** 

    Я согласен с выбранным ответом на использование DecimalFormat — или, альтернативно, BigDecimal .

    Пожалуйста, сначала прочтите « Обновить» !

    Однако, если вы хотите округлить двойное значение и получить результат с double значением, вы можете использовать org.apache.commons.math3.util.Precision.round(..) как указано выше. Реализация использует BigDecimal , медленна и создает мусор.

    Аналогичный, но быстрый и не содержащий мусора метод предоставляется утилитой DoubleRounder в библиотеке decimal4j:

      double a = DoubleRounder.round(2.0/3.0, 3); double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN); double c = DoubleRounder.round(1000.0d, 17); double d = DoubleRounder.round(90080070060.1d, 9); System.out.println(a); System.out.println(b); System.out.println(c); System.out.println(d); 

    Выйдет

      0.667 0.666 1000.0 9.00800700601E10 

    См. https://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility

    Отказ от ответственности: я участвую в проекте decimal4j.

    Обновление: Как отметил @iaforek, DoubleRounder иногда возвращает недопустимые результаты. Причина в том, что он выполняет математически правильное округление. Например, DoubleRounder.round(256.025d, 2) будет округлено до 256.02, потому что двойное значение, представленное как 256.025d, несколько меньше, чем рациональное значение 256.025 и, следовательно, будет округлено.

    Заметки:

    • Это поведение очень похоже на поведение конструктора BigDecimal(double) (но не на valueOf(double) который использует конструктор строк).
    • Сначала проблему можно обойти с двойным шагом округления до более высокой точности, но это сложно, и я не буду вдаваться в подробности здесь

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

    DecimalFormat – лучший способ вывода, но я не предпочитаю его. Я всегда делаю это все время, потому что он возвращает двойное значение. Поэтому я могу использовать его больше, чем просто вывод.

     Math.round(selfEvaluate*100000d.0)/100000d.0; 

    ИЛИ

     Math.round(selfEvaluate*100000d.0)*0.00000d1; 

    Если вам нужно большое значение десятичных знаков, вы можете использовать BigDecimal. В любом случае .0 важно. Без него округление 0,333333d5 возвращает 0,33333 и допускается только 9 цифр. Вторая функция без .0 имеет проблемы с возвратом 0.30000 0.30000000000000004.

    Для этого мы можем использовать этот форматтер:

      DecimalFormat df = new DecimalFormat("#.00"); String resultado = df.format(valor) 

    или:

     DecimalFormat df = new DecimalFormat("0.00"); : 

    Используйте этот метод для получения двух десятичных знаков:

      private static String getTwoDecimals(double value){ DecimalFormat df = new DecimalFormat("0.00"); return df.format(value); } 

    Определение этих значений:

     91.32 5.22 11.5 1.2 2.6 

    Используя этот метод, мы можем получить следующие результаты:

     91.32 5.22 11.50 1.20 2.60 

    демо онлайн.

    Имейте в виду, что String.format () и DecimalFormat производят строку, используя стандартный язык Locale. Таким образом, они могут писать форматированное число с точкой или запятой в качестве разделителя между целыми и десятичными частями. Чтобы убедиться, что округленная строка находится в формате, который вы хотите использовать java.text.NumberFormat, так:

      Locale locale = Locale.ENGLISH; NumberFormat nf = NumberFormat.getNumberInstance(locale); // for trailing zeros: nf.setMinimumFractionDigits(2); // round to 2 digits: nf.setMaximumFractionDigits(2); System.out.println(nf.format(.99)); System.out.println(nf.format(123.567)); System.out.println(nf.format(123.0)); 

    Будет печатать на английском языке (независимо от вашего местонахождения): 0,99 123,57 123,00

    Пример из Farenda – как правильно преобразовать double в String .

    Где dp = десятичное место, которое вы хотите, а значение – двойное.

      double p = Math.pow(10d, dp); double result = Math.round(value * p)/p; 

    If you Consider 5 or n number of decimal. May be this answer solve your prob.

      double a = 123.00449; double roundOff1 = Math.round(a*10000)/10000.00; double roundOff2 = Math.round(roundOff1*1000)/1000.00; double roundOff = Math.round(roundOff2*100)/100.00; System.out.println("result:"+roundOff); 

    Output will be: 123.0 1
    this can be solve with loop and recursive function.

    If you’re using a technology that has a minimal JDK. Here’s a way without any Java libs:

     double scale = 100000; double myVal = 0.912385; double rounded = (int)((myVal * scale) + 0.5d) / scale; 

    In general, rounding is done by scaling: round(num / p) * p

     /** * MidpointRounding away from zero ('arithmetic' rounding) * Uses a half-epsilon for correction. (This offsets IEEE-754 * half-to-even rounding that was applied at the edge cases). */ double RoundCorrect(double num, int precision) { double c = 0.5 * EPSILON * num; // double p = Math.pow(10, precision); //slow double p = 1; while (precision--> 0) p *= 10; if (num < 0) p *= -1; return Math.round((num + c) * p) / p; } // testing edge cases RoundCorrect(1.005, 2); // 1.01 correct RoundCorrect(2.175, 2); // 2.18 correct RoundCorrect(5.015, 2); // 5.02 correct RoundCorrect(-1.005, 2); // -1.01 correct RoundCorrect(-2.175, 2); // -2.18 correct RoundCorrect(-5.015, 2); // -5.02 correct 
    Interesting Posts

    Bootstrap 3 Navbar с логотипом

    Очистить кеш запросов MySQL без перезапуска сервера

    val () против text () для textarea

    Выберите правильный метод async для пакетной обработки для максимальных запросов / сек.

    Пользовательская панель вырезания / копирования для EditText, которая отображает дескрипторы выбора текста

    Мой компьютер включился. Был ли я взломан?

    Могу ли я решить эту проблему с помощью чистого mysql? (присоединение к ‘;’ разделенные значения в столбце)

    Лучший подход для синтаксического анализа XML на iPhone

    Есть ли замена на основе задачи для System.Threading.Timer?

    Можно ли выключить мышь средней кнопкой мыши?

    Возможно ли регистрировать события файловой системы в Windows или Linux?

    Что такое шаблон дизайна фасадов?

    Являются ли MAC-адреса уникальными при выходе из завода?

    Как заменить специальные символы в строке?

    Произвольное генерирование букв в соответствии с их частотой использования?

    Давайте будем гением компьютера.