반응형
[C/C++] float, double은 ==로 비교하면 안되는 이유
말 그대로 부동 소수점, C/C++에서는 float나 double로 불리는 자료형은 == 연산자로 비교해서는 안됩니다.
그 이유를 알아봅시다.
반응형
3.14 == 3.14는 거짓이다.
3.14를 비교하는 코드를 보겠습니다.
#include <stdio.h>
int main(void) {
double fval = 3.14;
printf("%.10lf %.10f \n", fval, (float)fval);
return 0;
}
같은 값이 나올까요? 아닙니다, 출력해보면 아래와 같이 오차를 포함하여 출력이 될겁니다. 오차 값은 때에 따라 달라질 수 있습니다.
float로 형변환한 것이 오차를 발생시키고, 같지 않다는 결과가 리턴된다.
컴퓨터는 소수를 표현하기 위해 대표적으로 두가지 방법을 사용합니다.
- 고정소수점 : 일정 비트는 소수점 위의 값(정수)을, 나머지 비트는 소수점 아래의 값을 저장하도록 하여 10진수 변환을 할 때 공간을 기준으로 변환을 처리. ( 고정 소수점 방식은 정확도는 높지만 큰 수를 표현하기 위해서는 많은 양의 메모리가 사용된다는 단점이 있음 )
- 부동소수점 : 고정소수점 문제를 해결하기 위해 개발됨. 현대 컴퓨터는 IEEE의 부동소수점 방식을 이용함.
반응형
어떻게 비교해야할까?
그렇다면 float나 double과 같은 실수 자료형은 어떻게 비교해야 할까요? 비교할 값의 차이가 오차보다 작음을 비교하면 됩니다.
#include <stdio.h>
#define ABS(X) ((X) < 0 ? -(X) : (X))
#define EPSILON 0.000001
int main(void) {
float fval = 3.14;
if (ABS(fval - 3.14) < EPSILON) {
printf("fval은 3.14입니다.\n");
}
else {
printf("fval은 3.14가 아닙니다.\n");
}
return 0;
}
반응형
이 때, 미세오차를 의미하는 EPSILON(입실론)은 비교할 자료형이 float이냐 double이냐에 따라 범위를 달리 해주어야합니다.
무엇보다 실수를 사용하지 않을 수 있다면 사용하지 않는 편이 좋습니다. 생각 외로 정수를 처리하는데 드는 비용보다 실수를 처리하는데 필요한 비용이 압도적으로 많기 때문에 만일 속도가 생명인 프로그램을 만들 생각이라면 실수보단 정수를 사용하는것이 좋습니다.
반응형
'IT > C C++' 카테고리의 다른 글
[C언어] 재귀함수(피보나치수열)는 자신을 return하면 안된다 (0) | 2023.10.22 |
---|---|
[C/C++] math.h로 정확한 파이값 사용하는 방법 (0) | 2023.05.25 |
[C/C++] 키보드 매크로 프로그램 만들기 (0) | 2023.03.30 |
[C/C++] 무조건 강제종료하기 (0) | 2023.03.30 |
[C/C++] Break/Return/Continue 차이 (0) | 2023.03.30 |