Nice programing

.NET의 부정확 한 소수

nicepro 2020. 12. 11. 19:24
반응형

.NET의 부정확 한 소수


어제 디버깅 중에 이상한 일이 발생하여 실제로 설명 할 수 없습니다.

소수점 계산

대괄호가있는 소수 계산

그래서 나는 여기서 명백한 것을 보지 못하거나 .NET에서 소수에 대해 오해했지만 결과가 동일하지 않아야합니까?


decimal나를 위해 모든 수학을 입력 하는 마법이 아닙니다 . 그것은 여전히 부동 소수점 숫자입니다 - 주요 차이점에서 float그것이라는 것이다 진수 보다는, 부동 소수점 숫자 이진 . 따라서 0.310 진수로 쉽게 표현할 수 있지만 (유한 이진수로는 불가능합니다) 무한 정밀도는 없습니다.

이것은 동일한 계산을하는 사람에게 훨씬 더 가깝게 작동하지만, 여전히 각 작업을 개별적으로 수행하는 사람을 상상해야합니다. 수학에서하는 것과 같은 종류의 작업을하지 않는 재무 계산을 위해 특별히 설계되었습니다. 단계별로 이동하여 매우 구체적인 규칙에 따라 각 결과를 반올림합니다.

사실, 많은 경우에는 decimal보다 훨씬 더 나쁘거나 float더 잘 작동 할 수 있습니다 double. 이는 decimal자동 반올림을 전혀 수행하지 않기 때문 입니다. 와 같은 일을하는 것은 double에서 -이 자동으로 차이가 중요하지 않습니다 가정 있기 때문에, 당신에게 예상대로 (22)을 제공 decimal그것이 않습니다 - 그에 대한 중요한 포인트 중 하나입니다 decimal. Math.Round물론 수동 s 를 삽입하여이를 에뮬레이션 할 수 있지만 그다지 의미가 없습니다.


Decimal정밀도 한계 내에서 정확히 10 진수로 표현 가능한 값만 저장할 수 있습니다. 여기서 22/24 = 0.91666666666666666666666 ... 저장하려면 무한 정밀도 또는 합리적인 유형이 필요하며 더 이상 반올림 후 22/24와 같지 않습니다.

먼저 곱셈을하면 모든 값을 정확하게 표현할 수 있으므로 결과가 표시됩니다.


대괄호를 추가하면 곱하기 전에 나누기가 계산됩니다. 이것은 부동 정밀도 문제를 일으킬만큼 계산에 영향을 미칠만큼 미묘하게 보입니다 .

컴퓨터가 실제로 가능한 모든 숫자를 생성 할 수는 없기 때문에이를 계산에 반영해야합니다.


하지만 Decimal보다 높은 정밀도를 가지고 Double, 그 차 유용한 기능은 모든 값이 있다는 것입니다 정확하게는 사람이 읽을 수있는 표현을 일치합니다 . 일부 언어에서 사용할 수있는 고정 소수점 유형은 일치하는 정밀도 고정 소수점 값 두 개를 더하거나 빼거나 고정 소수점 유형을 정수로 곱해도 반올림 오류가 발생하지 않으며 " Java에서 발견되는 것과 같은 big-decimal "유형은 곱셈이 반올림 오류를 일으키지 않음을 보장 할 수 있으며, Decimal.NET에서 발견되는 것과 같은 부동 소수점 유형은 그러한 보장을 제공하지 않으며, 나누기 연산이 완료 될 수 있음을 보장 할 수있는 소수 유형도 없습니다. 반올림 오류없이 (Java에는 반올림이 필요한 경우 예외를 던지는 옵션이 있습니다).

Decimal부동 소수점 유형 을 만들기 결정한 사람들 은 소수점 오른쪽에 더 많은 숫자가 필요한 상황이나 왼쪽에 더 많은 숫자가 필요한 상황에 사용할 수 있도록 의도했을 수 있지만 base-10 또는 base-2에 관계없이 부동 소수점 유형 , 모든 작업에 대해 반올림 문제를 피할 수 없도록 만듭니다.

참고 URL : https://stackoverflow.com/questions/32198081/inaccuracy-of-decimal-in-net

반응형