문제

(int)(33.46639 * 1000000) 보고 33466389

왜 이런 일이 발생합니까?

도움이 되었습니까?

해결책

플로팅 포인트 수학은 완벽하지 않습니다. 모든 프로그래머가 알아야 할 것 그것에 대해.

부동 소수점 산술은 많은 사람들이 난해한 주제로 간주됩니다. 부동 소수점은 컴퓨터 시스템에서 유비쿼터스이기 때문에 이것은 오히려 놀랍습니다. 거의 모든 언어에는 부동 소수점 데이터 유형이 있습니다. PCS에서 슈퍼 컴퓨터까지의 컴퓨터에는 부동 소수점 가속기가 있습니다. 대부분의 컴파일러는 수시로 부동 소수점 알고리즘을 컴파일하도록 요구됩니다. 그리고 거의 모든 운영 체제는 오버플로와 같은 부동 소수점 예외에 응답해야합니다. 이 백서는 컴퓨터 시스템의 설계자에게 직접적인 영향을 미치는 부동 소수점 측면에 대한 튜토리얼을 제시합니다. 부동 소수점 표현 및 반올림 오류에 대한 배경으로 시작하여 IEEE 플로팅 포인트 표준에 대한 논의로 계속 진행되며 컴퓨터 빌더가 부동 소수점을 더 잘 지원할 수있는 방법에 대한 수많은 예를 마무리합니다.

...

무한히 많은 실수를 유한 수의 비트로 압박하려면 대략적인 표현이 필요합니다. 무한한 정수가 있지만 대부분의 프로그램에서 정수 계산 결과는 32 비트로 저장 될 수 있습니다. 대조적으로, 고정 된 수의 비트가 주어지면 실수를 가진 대부분의 계산은 그 많은 비트를 사용하여 정확하게 표현할 수없는 수량을 생성합니다. 따라서 유한 표현으로 다시 맞추기 위해 부동 소수점 계산의 결과는 종종 반올림해야합니다. 이 반올림 오류는 부동 소수점 계산의 특징입니다.

다른 팁

이중 정밀도는 정확하지 않으므로 내부적으로 33.46639는 실제로 33.466389로 저장됩니다.

편집 : Richard가 말했듯이, 그것은 부동 소수점 데이터입니다 (이진에 유한 한 비트 세트로 저장 됨).

인텔의 CEO 인 앤디 그 로브 (Andy Grove)는 펜티엄 프로세서가 나오고 큰 타격을 입었을 때 좋은 해를 보냈습니다. 그래서 그는 술집에 들어가서 Johnnie Walker Green 라벨의 더블 샷을 주문했습니다.

바텐더는 그것을 제공하고 "20 달러가 될 것"이라고 말했다.

그 로브는 카운터에 20 달러의 지폐를 넣고 잠시 동안 그것을보고 말했다.

http://en.wikipedia.org/wiki/pentium_fdiv_bug

그 이유는 33.46639가 그 숫자보다 약간 적은 것으로 표현되기 때문입니다.

1000000을 곱하면 33466389.9999999가 제공됩니다.

(int)를 사용한 유형 캐스팅은 정수 부품 (33466389)을 반환합니다.

"오른쪽"숫자를 원한다면 유형 주조 전에 Round ()를 사용해보십시오.

왜 그렇지 않은지 묻는다면 33466390, 왜냐하면 doubles는 무한한 정밀도가 없으며 숫자는 이진으로 정확하게 표현할 수 없습니다.

당신이 교체하는 경우 double a decimal ((int)(33.46639m * 1000000)), 그것은 동일합니다 33466390, 왜냐하면 decimals는 기본 10에서 계산됩니다.

33.46639는 유한 수의 이진 숫자로 정확하게 표현할 수 없기 때문입니다. 33.46639 * 10000000의 실제 결과는 3346389.99999962747097015380859375입니다. 캐스트는 그것을 33466389로 잘립니다.

당신이 다른 결과를 얻은 이유는 당신이 a '를 사용했기 때문입니다.깁스'

(int)(33.46639 * 1000000) returns 33466389
^^^^^

결과를 'int'의 유형으로 캐스팅하려면 ... 곱하기가 곱하고 'int'로 변환 될 때 적분 유형을 둥글거나 아래로 내려 놓았습니다. .Skeet은 그의 사이트에 훌륭한 소개를 게시했습니다 여기 그리고 여기...

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