2 분 소요

이 글은 패스트캠퍼스 C++ 실력 완성 올인원 패키지 Online.를 보고 따라 만들면서 헷갈리는 부분을 정리한 글입니다.

부동 소수점 자료형

int가 정수형을 저장하는 자료형이라면 소수점을 저장하는 변수는 float, double, long double 등이 있다.

부동 소수점 선언

#include <iostream>
using namespace std;

int main()
{
	float f = 1.0;
	double d = 1.0;
	long double ld = 1.0;

	cout << sizeof(f) << endl;	// 4
	cout << sizeof(d) << endl;	// 8
	cout << sizeof(ld) << endl;	// 8
}

부동 소수점의 값은 뒤에 어떤 문자를 붙이냐에 따라 float, double, long double인지 정해진다.

#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{
	cout << typeid(1.0f).name() << endl;	// float (f를 붙임)
	cout << typeid(1.0).name() << endl;		// double(안붙임)
	cout << typeid(1.0L).name() << endl;	// long double(L을 붙임)
}

부동 소수점 주의해야할 점

오차가 작은 수의 비교

다음 예시를 보면 언뜻 눈으로 보기에는 두 값이 같아보이지만 비교해보면 두 값이 다르다고 나온다.

#include <iostream>
using namespace std;

int main()
{
	float num0 = 0.1f;
	float num1 = 0.02f * 5.0f;

	if (num0 == num1)
		cout << "두 값은 같다." << endl;	// X
	else
		cout << "두 값은 틀리다." << endl;	// 여기가 출력됨
}

이는 사실 두 값인 num0과 num1를 자세하게 출력해보면 알 수 있다.

float num0 = 0.1f;
float num1 = 0.02f * 5.0f;
cout.precision(64);

cout << num0 << endl;
cout << num1 << endl;


자세한 출력

사실 0.1이라는 숫자를 정확히 표현할 수 없어서 매우 유사한 값을 대입하기 때문에 비교했을 때 두 값이 같지 않은 상황이 발생한다.

자료형이 다른 부동소수점의 비교

또 다른 예시로는 다음과 같은 예시가 있다.
다음 예시는 부동소수점 자료형이 다르기 때문에 두 값이 같지 않다고된다.

#include <iostream>
using namespace std;

int main()
{
	float num0 = 0.1f;

	if (num0 == 0.1)
		cout << "0.1과 같다." << endl;	// X
	if (num0 == 0.1f)
		cout << "0.1f과 같다." << endl;	// O
	if (num0 == 0.1L)
		cout << "0.1L과 같다." << endl;	// X
}

매우 매우 작은 수와의 계산

인식하지 못할 정도의 작은 수와 함께 계산할 경우 아예 먹힐 수가 있다.

#include <iostream>
using namespace std;

int main()
{
	float num0 = 1.0f;
	
	
	// float 앱실론 보다 작은 값 (앱실론 -> 부동 소수점의 가장 작은 간격)
	unsigned int num1 = 0b00110011100000000000000000000000;
	float num2;
	memcpy(&num2, &num1, sizeof(num1));

	cout.precision(64);
	cout << num0  + num2; // num2가 먹혀서 그냥 1로 출력됨

	// 0011,1111,1000,0000,0000,0000,0000,0000  = 1.0(2)
	// 0011,0011,1000,0000,0000,0000,0000,0000  = 1.0(2) * (10^ -24)
}
// 출력 결과
// 1

큰 수와의 덧셈

또 한 반대로 큰 숫자와 계산할 때도 숫자가 먹힐 수 있다.

#include <iostream>
using namespace std;

int main()
{
	float num0 = 1.0f;
	
	// float 앱실론 보다 작은 값 (앱실론 -> 부동 소수점의 가장 작은 간격)
	unsigned int num1 = 0b01001011100000000000000000000000;
	float num2;
	memcpy(&num2, &num1, sizeof(num1));

	cout.precision(64);
	cout << num2 << endl; // 16777216
	cout << num0  + num2; // 16777216   (1이 먹혀서 사라짐)

	// 0011,1111,1000,0000,0000,0000,0000,0000  = 1.0(2)
	// 0100,1011,1000,0000,0000,0000,0000,0000  = 1.0(2) * (10^ 24)
}
// 출력 결과
//16777216
//16777216

태그:

카테고리:

업데이트:

댓글남기기