저번에 정수형에 대해 알아봤다면 이번에는 부동소수점에 대해 알아보자. (조금씩 진행되어 가는게 흐뭇^^)
부동소수점 : 점이 움직인다. 즉, 100 = 1.0 * 100
표현할 방법은 무궁무진하다.
전 시간에도 말했지만, sizeof()
를 사용해서 직접 확인하는 것이 좋다.
부호 쪽이 0이면 +, 1이면 - 이다.
코드로 이해해보자.
#include <iostream>
#include <limits>
int main()
{
using namespace std;
float f;
double d;
long double ld;
cout << numeric_limits<float>::max() << endl;
cout << numeric_limits<double>::max() << endl;
cout << numeric_limits<long double>::max() << endl;
cout << endl;
cout << numeric_limits<float>::lowest() << endl;
cout << numeric_limits<double>::lowest() << endl;
cout << numeric_limits<long double>::lowest() << endl;
cout << numeric_limits<long double>::min() << endl;
return 0;
}
output : 3.40282e+38
1.79769e+308
1.79769e+308
-3.40282e+38
-1.79769e+308
-1.79769e+308
2.22507e-308
sizeof()
를 사용하여 자료형의 크기를 알아볼 순 있지만, 정확하게 그것이 어느 수까지 표현하는지 알고 싶으면 #include <limits>
를 사용해 보는 것이 좋다. 저번 시간에도 했지만, 종종 사용되므로 사용법을 알아두자!!
cout << numeric_limits<long double>::max() << endl;
는 뭔지 알겠는데, min()
과 lowest()
의 차이는 무엇일까? 어떤 의미인 걸까?... 정보를 찾아보면 min()
같은 경우에는 가장 작은 유한수로 나오고 lowest()
같은 경우에는 가장 낮은 유한수로 나온다. 이게 무슨 의미인지... 알아보자.
min()
: 절댓값이 0은 아니지만 그 중에서 제일 작은 수이다. (음수가 나올 수 없다.)
lowest()
: 표현할 수 있는 수에서 제일 낮은 수이다. (음수가 나올 수 있다.)
지금은 이해가 안가도 나중에 써보면 이해가 될 것이므로 이해가 안되면 패스~~~!!!!
다음 코드를 이해해보자.
#include <iostream>
#include <limits>
int main()
{
using namespace std;
float f(3.14);
cout << 3.14 << endl;
cout << 31.4e-1 << endl;
cout << 31.4e-2 << endl;
cout << 31.4e1 << endl;
cout << 31.4e2 << endl;
return 0;
}
output : 3.14
3.14
0.314
314
3140
이 코드에서 딱히 어려운건 없다. 다만 e에 대해서 짚고 넘어갈려 한다. 이 e = 10
과 같다라고 생각하면 된다. e가 곱해져있으면 10이 곱해져 있구나 라고 생각하자. 따라서 e1
이면 10^1이고 e-1
이면 10^-1이다. 어려운 개념은 아니다.
(ex. 어떤 수에 100을 곱하는 것보다 e2를 넣어 가독성을 높이는 방법도 있다.)
#include <iostream>
#include <iomanip>
#include <limits>
int main()
{
using namespace std;
double d1(1.0);
double d2(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
//cout << std::setprecision(17);
cout << d1 << endl;
cout << d2 << endl;
return 0;
}
output : 1
1
생각을 정말 잘해야 하고 오류를 범하기 쉬운 내용으로 넘어가 보도록 하겠다. C언어에서도 마찬가지지만, 1.0과 0.1을 10번 더한 것과 출력하면 값이 같을까? 다를까? output에 출력된 것을 보면 같다. 그래서 역시 같은 것이 아닐까 하고 생각할 수 있는데, 전혀 그렇지 않다. setprecision()
은 입출력 조작기이며 부동소수점 숫자의 기본 정밀도를 수정할 수 있다. ()안에 3을 넣으면 소수점 3번째 자릿수까지 출력하게 해준다. 이를 사용해서 출력하면 어떻게 될까?
#include <iostream>
#include <iomanip>
#include <limits>
int main()
{
using namespace std;
double d1(1.0);
double d2(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
cout << std::setprecision(17);
cout << d1 << endl;
cout << d2 << endl;
return 0;
}
output : 1
0.99999999999999989
오차들이 누적되어 이러한 결과가 나오는 것이다. 별거 아니라고 생각할 수 있긴 하지만 게임이나 과학에선 엄청난 오류를 일으킬 수 있으므로 조심하도록 하자.