F.R.I.D.A.Y.

부동소수점은 ==으로 비교하지 마세요 본문

DEV/C C++

부동소수점은 ==으로 비교하지 마세요

F.R.I.D.A.Y. 2019. 4. 5. 14:20
반응형

  말 그대로 부동 소수점, 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로 형변환한 것이 오차가 생깁니다.

 

 어째서 이런 일이 벌어질까요?

 컴퓨터는 소수를 표현하기 위해 대표적으로 두가지 방법을 사용합니다.

  1. 고정소수점
  2. 부동소수점

 간단히 설명하면 고정소수점방식은 일정 비트는 소수점 위의 값(정수)을, 나머지 비트는 소수점 아래의 값을 저장하도록 하여 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이냐에 따라 범위를 달리 해주어야합니다. 이유는 자료형이 보증하는 소수의 자릿수가 다르기 때문입니다. float은 소수점 아래 6자리, double은 소수점 아래 15자리 정확도를 보인다고 하네요.

 

2021.09.11.(Wed) 추가

 부동소수점 자료형은 데이터를 저장하는 방식에 있어 정수를 저장하는 방식과 상당한 차이를 보이기 때문에 유효 자릿수의 의미가 없습니다. 공부하던 당시 표준 기반으로 공부하지 않았기 때문에 잘못된 정보로 작성한 것 같네요.

 

더보기

# 2019.11.26.(Tue) 추가

 일부 코드상 문제를 발견해 수정했습니다. 수정된 부분은 다음과 같습니다.

#define ABS(X) (X < 0 ? -X : X)
// 위의 코드가 아래처럼 변경되었습니다.

#define ABS(X) ((X) < 0 ? -(X) : (X))

 변경된 이유는 아래 링크를 참고하세요.

 

 

매크로 함수를 사용할 때 주의할 점

조금 복잡한 계산들. 즉, 복잡한 수식들을 반복해서 작성하기는 여간 귀찮은 것이 아닙니다. 그래서 우리는 전처리 명령어(define)를 이용해서 매크로 함수로 그 수식을 대신하곤 합니다. 이번 포스트에서는 이..

pang2h.tistory.com

 

 무엇보다 실수를 사용하지 않을 수 있다면 사용하지 않는 편이 좋습니다. 생각 외로 정수를 처리하는데 드는 비용보다 실수를 처리하는데 필요한 비용이 압도적으로 많기 때문에 만일 속도가 생명인 프로그램을 만들 생각이라면 실수보단 정수를 사용하는것이 좋습니다.


더 알아보기

 

 

부동소수점

실수를 표현하기 위해 C언어에서는 대표적으로 float와 double 자료형이 존재합니다. 이 자료형들이 어떻게 데이터를 가지고 해석하는지 알아봅니다. 실수를 표현하는 방법 우리 일상에는 나이, 날짜, 지폐와 같..

pang2h.tistory.com

 

# index

728x90
반응형

'DEV > C C++' 카테고리의 다른 글

숫자의 형변환  (2) 2019.04.11
변수 초기화  (0) 2019.04.06
C/C++ 표준 코드(main 함수 표준)  (0) 2019.03.25
C언어 프로젝트 생성하기  (0) 2019.03.12
홀수 마방진 풀기  (0) 2019.03.09
Comments