728x90
728x90
SMALL
Chapter2. 변수와 기본 자료형
부동소수점수
영역 | 데이터 형 | 최소 크기 | 전형적인 크기 |
부동소수점 | float | 4byte | 4byte |
부동소수점 | double | 8byte | 8byte |
부동소수점 | long double | 8byte | 8 or 12 or 16 byte |
float의 내부
Q. 0000011111000000000000000000000 이 이진수를 float 실수로 어떤 수인지 알아보자
\[0 \ \ 0000111\ \ 11000000000000000000000 = +1.313554 \ * 10^{-36}\]
- float
ο 4 byte = 32bits = 총 32자리 - 부호 비트
ο 1자리
ο 0 이므로 +양수이다.
\[00000111 = 2^0 +2^1+2^2=7\]
- 지수 비트
ο 8자리
ο 00000111
ο 십진수로 7 이다.
\[11000000000000000000000=2^{-1}+2^{-2}=0.5 +0.25 = 0.75\]
- 가수 비트
ο 23자리
ο 왼쪽 앞부터 \[($2^-1)\] 이며 소수 자리를 나타낸다.
■ -1, -2, -3, -4, …. 순
ο 십진수로 0.75이다.
\[+(1+0.75)\ * \ 2^{(7-127)} = +1.313554 \ * 10^{-36}\]
- +
- (( 1 + 0.75 ))
ο 가수 비트 십진수 값에 1 더해주기 - (2^{7-127})
ο 지수 비트 십진수 값에 127을 빼주는 이유는 32bit 기준으로 메모리에 값을 저장할 때 따르는 규칙이라고 보면 된다. - $+ ( 1 + 0.75 ) * 2^{7-127}$ 을 계산한 값이 (+1.313554 * 10^{-36}) 가 된다.
std::numeric_limits<타입>::lowest()
- min : 가장 작은 절대값
- lowest : 가장 작은 값. 음수일 수도.
- 각각 float, double, long double 이 표현할 수 있는 범위 중에서 가장 작은 값을 리턴해준다.
실수의 다양한 표현 방법
- float f((3.14))
ο double형인 3.14를 float으로 자동으로 형 변환해주어 저장한다. C++에서만 가능.
ο float f{3.14} 대괄호 사용은 엄격하여 형변환 불가능
\[e-1 = *10^{-1}, \ e2 =*10^2\]
float f(3.14)
cout << 3.14 << endl;
cout << 31.4e-1 << endl; // 3.14 출력
cout << 31.4e-2 << endl; // 0.314 출력
cout << 31.4e1 << endl; // 3.14 출력
cout << 31.4e2 << endl; // 3.14 출력
std::setprecision((n))
- #include <iomanip>
ο 입출력 조작하는 라이브러리 - 자리 수를 지정한다.
ex1)
cout << setprecision(16) << endl;
cout << 1.0 / 3.0 << endl;
- cout « setprecision((16)) « endl;
ο 출력 스트림에 16자리까지 보장하도록 정보를 보낸다. - cout « 1.0 / 3.0 « endl;
ο 평소같으면 0.333333 이 정도 자리수의 정밀도만 보장할텐데
ο setprecision((16))으로 16자리까지 꼭 출력하도록 됐기 때문에
ο 0.3333333333333333 출력
정밀도 차이가 쌓이소 쌍이면 버그나 잡기 힘든 에러가 생길 수 있다
- 실수 표현의 원리
ο 이진수로 만드는거기 때문에 최대한 가깝게 표현하는 것이다.
ο 0.25 처럼 $2^{-2}$로 딱 떨어지는 이진수 소수라면 100% 정확하지만
ο 0.1 처럼 십진수 소수라면 그냥 이진수의 합의 조합들로 최대한 0.1에 가깝게 만드는 것이다.
ο 그러므로 정확한 값과 차이가 존재한다.
ο 정밀도가 높을 수록 최대한 가깝게 만들어 보는 것.
ex2)
double d(0.1);
cout << d << endl;
cout << std::setprecision(17);
cout << d << endl ;
- cout « d « endl;
ο 0.1 출력
■ 사실 딱 떨어지는 0.1이 아니고 내부적으로 최대한 0.1에 가깝게 만든 것이다. - cout « std::setprecision((17));
ο 출력 스트림에 16자리까지 보장하도록 정보를 보낸다. - cout « d « endl ;
ο 0.1000000000000001
ο 17자리로 출력하니 안보이던 끝에 1이 보인다.
ο 실제론 17자리 그 이상이였던 것 !!!!!!!!!!!!!!!!!!!!!!!!!!
ο 이렇게 이진수들의 합으로 십진수인 0.1에 최대한 가깝게 만든 것!
ex3)
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;
- cout « d1 « endl;
ο 1 출력
ο 17자리까지 안간다. 그냥 딱 떨어진 1 한자리 출력
ο 1은 2의 0승이기 때문에 이진수로 표현이 깔끔하게 가능하기 때문이다.
ο 실제로 딱 1 한자리 - cout « d2 « endl;
ο 0.99999999999999999
ο 1.0이 아닌 0.99999999999999999 로 나오는 이유
■ 각각 더해주는 0.1를 이진수로 표현을 먼저 한 후 더해주기 때문이다.
■ 이진수로 0.1은 딱 떨어지는 수가 아니기 때문에 이진수로 최대한 표현하다보니 차이가 생기는 것.
■ 이들을 다 더하니 1.0에 가까워지긴 했지만 딱 떨어지는 1.0은 아니다.
728x90
300x250
LIST
'C │ C++ │ C# > C++' 카테고리의 다른 글
C++ Chapter 2.6 : 문자형 char type (0) | 2023.08.15 |
---|---|
C++ Chapter 2.5 : Boolean 자료형과 조건문 if (0) | 2023.08.15 |
C++ Chapter 2.3 : void (0) | 2023.08.14 |
C++ Chapter 2.2 : 정수형((Integer)), 고정 너비 정수 (0) | 2023.08.13 |
C++ Chapter 2.1 : 기본 자료형 소개 (0) | 2023.08.13 |