2013-07-25 3 views
-1

나는 왜 이것이 일어나고 있는지를 알아 내려고 거의 하루 종일 보냈다. 정수가 될 때까지 부동 소수점을 증가시킨 코드를 가지고 있었고, 값을 0.01 씩 증가 시켜서 트리거했다. 루프는 정수가 될 때까지 0.01 씩 계속 증가하지만, 결코 멈추지 않습니다. 디버깅이 끝나면 점점 더 부정확 해지는 숫자로 루프가 진행됨에 따라 결국 0.0000066이됩니다.
나는 아마 변수가 다른 곳에서 액세스하고 있었다 수 어떻게 든 내가 단순히 빈 "주"프로그램을 만든 생각 :루프의 값이 증가하면 다른 (잘못된) 값이 생성됩니까?

float value = 0; 
for (int i=0; i<100; i++) { 
    value += 0.01f; 
} 
System.out.println(value); // Displays 0.99999934 
System.out.println(value == 1); // Just in case it's displaying wrong in println (displays false) 

왜 말까지 일이 아닌가요? 나는 그것이 float에 float을 추가 할 때 데이터 유형과 관련이있을 수 있다고 생각하지 않습니다.

+9

[모든 부동 소수점 연산에 대해 알아야 할 사항] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg .html) –

+0

@MadProgrammer 0-99는 여전히 100 회 반복됩니다. 100 * 0.01 = 1 – DannyMo

+1

@MadProgrammer 아니요, 100 배가 될 것 같습니다. '<= 100'을하면 101 번 반복됩니다. –

답변

5

Java의 부동 소수점 숫자는 IEEE floating point standards을 따르므로 0.01과 같은 값은 완벽하게 표현할 수 없습니다 (이진수에서는 반복되는 십진수입니다). 0.01을 표시 할 때 보이지 않는 작은 오류가 있습니다 (String으로 변환하면 반올림되지만) 모든 추가 (또는 다른 연산 작업)시 오류가 누적됩니다. 눈에 보이는 효과가 나타났습니다.

double을 두 배 정밀도로 사용하면 부동 소수점 오류를 줄일 수 있지만 결국 부동 소수점 오류가 표시됩니다. 임의의 정밀도를 지원하는 BigDecimal을 사용할 수도 있습니다.

+0

정수를 사용하여 나눌 것이라고 생각합니다. 나는 이것을 기억해야 할 것이다. 분명히 이것이 일어나지 않았 으면 좋겠다. –

0

예 부동 소수점 IEEE specification에 문제가 있습니다. 응용 프로그램에서 정밀도가 중요한 경우에는 BigDecimal

관련 문제