문제

ticketPriceInPence = 7360
percentageToRefund = 100

(int)(Math.Round((ticketPriceInPence * 0.01) * (percentageToRefund * 0.01), 2, MidpointRounding.AwayFromZero) * 100)

결과 : 73.59

(int)(Math.Round((ticketPriceInPence * 0.01) * (percentageToRefund * 0.01) * 100, 2, MidpointRounding.AwayFromZero))

결과 : 73.60

왜 다른 2 가지 결과를 초래하는지 아는 것

도움이 되었습니까?

해결책

그건 오래된 경우 부동 소수점 번호는 할 수 없습니다 정확히 소수성을 나타냅니다.

당신은 여기서 돈을 다루고있는 것 같고 실제로 사용을 고려해야합니다. 소수.

decimal ticketPriceInPence = 7360;
decimal percentageToRefund = 100;
var result1 = (int)(Math.Round((ticketPriceInPence * 0.01m) * (percentageToRefund * 0.01m), 2, MidpointRounding.AwayFromZero) * 100);
var result2 = (int)(Math.Round((ticketPriceInPence * 0.01m) * (percentageToRefund * 0.01m) * 100, 2, MidpointRounding.AwayFromZero));

다른 팁

간단한 대답은 부동 소수점 번호를 사용하는 방정식의 반올림 오류 때문이라는 것입니다. 이것은 일반적으로 부동 소수점 번호의 정확한 이진 표현이 없기 때문에 근사치 만 있으면됩니다.

나는 당신이 가지고있는 것을 알았습니다.

(percentageToRefund * 0.01)

첫 번째 방정식에서 :

(percentageToRefund * 0.01) * 100

두 번째.

후자의 표현식은 처음 100으로 나누고 다시 100을 곱하면 반올림 오류를 초래할 것입니다. 입력은 기계 아키텍처, OS, 언어 및 컴파일러에 따라 출력, 차이와 같지 않습니다.

돈을 다루고 있다면 사용해야합니다 decimal 유형 (C#가정)

플로트는 정확한 숫자가 아니기 때문입니다. 나는 읽는 것이 좋습니다 http://en.wikipedia.org/wiki/floating_point. 결과가 다른 이유를 알 수 있습니다.

짧은 이야기. 플로트 값을 이진 데이터로 나타낼 때 정밀한 오류 때문입니다. 즉, 기본적으로 32/64 비트로 가능한 모든 플로트를 대표 할 수는 없으므로 실제로 2.1은 2.1000000000000001 등입니다. 이것이 2.145 == "2.145 여야하는 기타 값"과 같은 일을하지 말아야 할 이유 중 하나입니다.

자세한 정보는 Wikipedia의 기사를 읽는 것이 좋습니다. 위키 링크

이것은 부동 소수점 번호의 유한 정밀성 때문입니다.

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