패스트캠퍼스 C++ 실력 완성 올인원 패키지 Online 수강 내용 중, 공부한 내용을 올립니다.
(강추입니다..)
C++ 부동소수점
1. 부동소수점 이란?
- 부동소수점은 실수를 표현하는 방법이다.
- C++에서는 보통 float: 32 bit이며, 이 중 지수부는 8bit, 가수부는 23 bit, 부호부는 1bit를 사용한다.
- double은 64 bit이며, 지수부 11bit, 가수부 52 bit, 부호부 1bit를 사용한다.
- long double은 64~128 bit 를 사용한다.
- 개발환경에 따라 달라지므로 확인이 필수이며, 필요에 따라 bit값을 고정하여 실수를 선언한다.
float num0 = 1;
double num1 = 1;
long double num2 = 1;
cout << sizeof(num0) << endl;
cout << sizeof(num1) << endl;
cout << sizeof(num2) << endl;
// c++에서 실수는 double이 디폴트임.
// float이나 long double 이용해서 형변환 하는꼴.
cout << sizeof(1.0f) << endl;
cout << sizeof(1.0) << endl;
cout << sizeof(1.0L) << endl; // Long double
//하지만 Integer와 마찬가지로 개발환경에 따라 달라짐.
2. 부동소수점 예시
예) -118.625
- 해당 실수를 이진수로 변환하면, -1110110.101 이 된다.
- 이것을 10의 제곱수로 표현하면, -1.110110101 10e6 (2)가 된다.
*여기서 10e6은 10^(6) 이며, (2)는 binary 라는 뜻이다.
- -1.110110101 10e(6)의 경우,
1) 부호부: 1 (음수)
2) 가수부: 1000 0101
3) 지수부: 1 1011 0101
- 가수부, 지수부를 따져보자.
*가수부.
- 가수부의 경우, float 32bit 중 8비트 이다.
- 0000 0000이 127을 나타내는데, 이는 가수부가 10의 음수 제곱일 경우를 대비해서 이다.
- 10의 '6' 제곱의 경우, 127+6 = 133이며,
- 133 to binary = 1000 0101 이다.
*지수부
- 지수부는 소수점 숫자 이다.
unsigned int a;
float b = -118.625;
memcpy(&a, &b, sizeof(b)); // b의 값을 a로 카피 한다. 메모리 상의 값을 직접 복사
cout << a << endl; //a의 값을 binary 로 변환하면, 위에서 구한 값이 됩니다.
cout << b << endl;
3. 주의 사항
- 10진수 0.1이나 0.02는 2진수로 표현할 수 없다.
- 컴퓨터는 가장 근접한 숫자로 이를 표현한다.
// 주의해야 할 점!! (굉장히 조심해야 함.)
float num_A = 0.1f;
float num_B = 0.02f * 5.0f;
cout << "\n주의" << endl;
cout << num_A << endl;
cout << num_B << endl;
if (num_A == num_B)
cout << "Equal" << endl;
else
cout << "No Equal" << endl;
cout.precision(64);
cout << "\n정밀도 확인" << endl;
cout << num_A << endl;
cout << num_B << endl;
if (num_A == num_B)
cout << "Equal" << endl;
else
cout << "No Equal" << endl;
- 이를 대비하기 위해 Epsilon 을 사용할 수 있는데,
이는 표현 가능한 가장 작은 숫자를 사용하여, 차이값 확인을 통해 숫자가 같은지 비교하는 방법이다.
- 하지만, Epsilon 은 사용할 때마다 오차가 누적되므로, 이 또한 주의가 필요하다.
float testA = 1.0f;
float testB = 0.0f;
for (int i = 0; i < 1000; i++)
{
testB = testB + 0.001;
}
if (testA == testB)
cout << "equal, 1.0f = 0.001 * 1000" << endl;
4. float의 최대값을 구해보자.
- 아래와 같이 생긴 것이 float의 최대값이라고 예상할 수 있다.
- 하지만 값이 이상하다.
- 지수부가 다 1이면 not a number 이기 때문이다.
unsigned int flt_max = 0b01111111111111111111111111111111;
float flx_max_tmp;
memcpy(&flx_max_tmp, &flt_max, sizeof(flt_max));
cout << flx_max_tmp << endl; //값이 이상함.
// 지수부가 다 1이면 Not A Number 임.
// 지수부에서 1을 빼야함.
- 지수부가 11111110인 것이 float의 최대값이다.
unsigned int flt_max2 = 0b01111111011111111111111111111111;
float flx_max_tmp2;
memcpy(&flx_max_tmp2, &flt_max2, sizeof(flt_max2));
cout << flx_max_tmp2 << endl; // 최대값
5. 무한대의 표현
- 지수부가 다 1이고, 가수부가 다 0이면 무한대 이다.
unsigned int flt_max3 = 0b01111111100000000000000000000000;
float flx_max_tmp3;
memcpy(&flx_max_tmp3, &flt_max3, sizeof(flt_max3));
cout << flx_max_tmp3 << endl;
'공부 > C++' 카테고리의 다른 글
C++, 열거형 Enumerate type (0) | 2024.05.06 |
---|---|
C++ Integer, 정수 최대 최소 및 크기 (0) | 2024.04.12 |
백준 알고리즘 1004번, 어린왕자 (C++) (0) | 2024.01.08 |
백준 1008번 (C++) (3) | 2024.01.01 |
C++ 백준 1002번 (1) | 2023.12.25 |
선형 대수 - 13. 선형 부분공간 (4) | 2023.11.02 |
선형 대수 - 8. 벡터의 정의 및 연산 (7) | 2023.09.26 |
C++과 Python의 차이, 컴파일 언어와 인터프리터 언어의 차이 (83) | 2023.09.07 |