문제

최근에 나는 java.math.MathContext 그러나 제대로 이해하지 못했습니다.반올림에 사용됩니까? java.math.BigDecimal.그렇다면 왜 소수점 이하 자릿수를 반올림하지 않고 가수 부분까지 반올림합니까?

API 문서를 통해 다음에 명시된 표준을 따른다는 것을 알게 되었습니다. ANSI X3.274-1996 그리고 ANSI X3.274-1996/AM 1-2000 사양이 있지만 온라인에서 읽도록 하지 못했습니다.

이에 대해 어떤 생각이 있으면 알려주시기 바랍니다.

도움이 되었습니까?

해결책

@jatan

답변해주셔서 감사합니다.말된다.BigDecimal#round 메소드의 맥락에서 MathContext에 대해 설명해 주시겠습니까?

특별한 것은 없습니다 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

정밀도와 반올림 모드가 모두 출력에 영향을 미치는 것을 볼 수 있습니다.

다른 팁

BigDecimal의 소수 부분만 반올림하려면 다음을 확인하세요. BigDecimal.setScale(int newScale, int roundingMode) 방법.

예:소수점 이하 세 자리 숫자를 두 자리 숫자로 변경하고 반올림하려면 다음을 수행하세요.

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

결과는 값이 1.24인 BigDecimal입니다(반올림 규칙으로 인해).

여기에 몇 가지 예를 추가하겠습니다.이전 답변에서는 찾지 못했지만 오해를 불러일으킬 수 있는 사람들에게 유용하다고 생각합니다. 유효 숫자 수와 함께 소수점 자리.다음과 같은 맥락이 있다고 가정해 보겠습니다.

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

이 명백하지만 관련 있는 예가 도움이 되기를 바랍니다.

내가 당신을 올바르게 이해하고 있다면 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

재미를 위한 것이 아닙니다.실제로 나는 사용을 명시한 온라인 예제를 찾았습니다. MathContext BigDecimal에 저장된 금액/숫자를 반올림합니다.

예를 들어,

만약에 MathContext 가지도록 구성되어 있습니다 precision = 2 그리고 rounding mode = ROUND_HALF_EVEN

BigDecimal Number = 0.5294, 이다 둥근 에게 0.53

그래서 나는 그것이 새로운 기술이라고 생각하고 반올림 목적으로 사용했습니다.그러나 숫자의 멘티사 부분까지 반올림하기 시작하면서 악몽으로 변했습니다.

예를 들어,

Number = 1.5294 반올림됩니다 1.5

Number = 10.5294 반올림됩니다 10

Number = 101.5294 반올림됩니다 100

....등등

따라서 이것은 반올림에 대해 예상했던 동작이 아닙니다(정밀도 = 2).

패턴에서 숫자의 처음 두 자리(정밀도는 2이므로)를 취하고 숫자까지 0을 추가한다고 말할 수 있기 때문에 일부 논리가 있는 것 같습니다.자릿수는 반올림되지 않은 금액과 동일해집니다(101.5294 ...의 예를 확인하세요).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top