Использование java.math.MathContext

голоса
42

Недавно я пытался понять использование java.math.MathContext , но не правильно понять. Это используется для округления java.math.BigDecimal, если да , то почему он не круглый десятичных цифр , но даже mentissa части.

Из API Docs, я узнал , что он соответствует стандарту , указанному в ANSI X3.274-1996и ANSI X3.274-1996/AM 1-2000спецификации , но я не получил их читать онлайн.

Пожалуйста, дайте мне знать, если у вас есть какие-либо идеи по этому вопросу.

Задан 11/08/2008 в 06:23
источник пользователем
На других языках...                            


5 ответов

голоса
54

Для округления только дробную часть BigDecimal, проверьте BigDecimal.setScale(int newScale, int roundingMode)метод.

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

BigDecimal original = new BigDecimal("1.235");
BigDecimal scaled = original.setScale(2, BigDecimal.ROUND_HALF_UP);

Результатом этого является BigDecimal со значением 1,24 (из-за округления до правила)

Ответил 16/11/2010 в 13:55
источник пользователем

голоса
36

@jatan

Спасибо вам за ответ. Это имеет смысл. Можете ли вы объяснить мне MathContext в контексте BigDecimal # круглого метода.

Там нет ничего особенного BigDecimal.round() против любого другого BigDecimalметода. Во всех случаях, MathContextуказывает количество значащих цифр и техника округление. В принципе, есть две части каждый MathContext. Там в точности, и есть также RoundingMode.

Точность снова задает количество значащих цифр. Так что, если вы укажете в 123качестве номера, и попросите 2 значащих цифр, что вы собираетесь получить 120. Это может быть яснее , если вы думаете , с точки зрения научной нотации.

123будет 1.23e2в научной нотации. Если вы только сохранить 2 значащих цифр, то вы получите 1.2e2, или 120. За счет уменьшения количества значащих цифр, мы снижаем точность , с которой мы можем указать номер.

RoundingModeЧасть определяет , как мы должны справиться с потерей точности. Для повторного использования в качестве примера, если вы используете в 123качестве числа, и попросите 2 значащих цифр, вы уменьшить вашу точность. С RoundingModeиз HALF_UP(режим по умолчанию), 123будет 120. С RoundingModeо CEILING, вы получите 130.

Например:

System.out.println(new BigDecimal("123.4",
                   new MathContext(4,RoundingMode.HALF_UP)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(2,RoundingMode.HALF_UP)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(2,RoundingMode.CEILING)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(1,RoundingMode.CEILING)));

Выходы:

123.4
1.2E+2
1.3E+2
2E+2

Вы можете видеть, что как точность и режим округления влияет на выход.

Ответил 11/08/2008 в 07:06
источник пользователем

голоса
9

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

MathContext MATH_CTX = new MathContext(3, RoundingMode.HALF_UP);

Для этого кода:

BigDecimal d1 = new BigDecimal(1234.4, MATH_CTX);
System.out.println(d1);

это совершенно ясно, что ваш результат , 1.23E+3как было сказано выше , ребята. Во- первых значимые цифры 123 ...

Но что в этом случае:

BigDecimal d2 = new BigDecimal(0.000000454770054, MATH_CTX);
System.out.println(d2);

Ваш номер не будет округлена до 3 -х знаков после запятой - для кого - то это может быть не интуитивным и стоит подчеркнуть. Вместо этого оно будет округлено до первых 3 значащих цифр , которые в этом случае являются «4 5 4». Так выше код приводит 4.55E-7и не 0.000кто - то мог ожидать.

Подобные примеры:

BigDecimal d3 = new BigDecimal(0.001000045477, MATH_CTX);
 System.out.println(d3);  // 0.00100

BigDecimal d4 = new BigDecimal(0.200000477, MATH_CTX);
 System.out.println(d4);   // 0.200

BigDecimal d5 = new BigDecimal(0.000000004, MATH_CTX);
    System.out.println(d5); //4.00E-9

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

Ответил 10/04/2014 в 14:06
источник пользователем

голоса
4

Это не для удовольствия. На самом деле я нашел некоторые интернет - пример, в котором говорилось , использование MathContextокруглять Количества / номеров , сохраненных в BigDecimal.

Например,

Если MathContextсконфигурирован , чтобы иметь precision = 2иrounding mode = ROUND_HALF_EVEN

BigDecimal Number = 0.5294, Имеет закругленные до 0,53

Поэтому я подумал, что это новая техника и использовал его для округления цели. Однако она превратилась в кошмар, потому что он начал округления даже mentissa части числа.

Например,

Number = 1.5294 округляется до 1.5

Number = 10.5294 округляется до 10

Number = 101.5294 округляется до 100

.... и так далее

Так что это не поведение, я ожидал округление (как точность = 2).

Казалось бы, имея некоторую логику, потому что с скороговоркой я могу сказать, что она занимает первые две цифры (как точность 2) числа, а затем присоединяет 0 'пока нет. цифр становится такой же, как неокругленные суммы (проверка на примере 101.5294 ...)

Ответил 11/08/2008 в 06:45
источник пользователем

голоса
4

Если я правильно понять вас, это звучит , как вы ожидали MathContext контролировать , сколько цифр должно быть после запятой. Это не то , что это для. Он определяет , сколько цифр сохранить, общие . Так что если вы указываете , что вы хотите , 3 значащие цифры, это все , что вы собираетесь получить.

Например, это:

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(20)));

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(10)));

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(5)));

Выведет:

1234567890.123456789
1234567890
1.2346E+9
Ответил 11/08/2008 в 06:44
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more