https://www.h-schmidt.net/FloatConverter/IEEE754.html
부호 + 지수 + 가수
sign + exponent + mantissa
컴퓨터는 수를 표현 할 때 2진수로 만드는 것이기 때문에 최대한 가깝게 표현한다.
실수를 다룰 때 정확한 값과 차이가 있을 수 있다.
부호 : 1비트. 숫자의 부호를 나타내며, 양수일 때 0, 음수일 때 1이 된다.
지수부 : 8비트. 지수를 나타낸다.
가수부 : 23비트. 가수 또는 유효숫자를 나타낸다.
부동 소수점으로 변환
1. 부호를 확인한다. 32bit의 맨 앞자리 양수라면 0, 음수라면 1이 들어 간다.
2. 숫자의 절대값을 2진수로 표현한다. 그리고 소수점을 왼쪽으로 이동 시켜 소수점 왼쪽에 하나만 남겨둔다.
예를 들어 1.00111010101 x 2^8 과 같은 형태로 나올 것이다.
위와 같은 경우는 지수가 8이라는 것을 알 수 있다.
소수점의 오른쪽 부분을 가수부 23비트의 앞에서 부터 채우고 남은 부분은 0으로 채운다.
3. 지수부를 채운다.위에서 8 이었다. 그렇다면 bias(약속) 127을 8에 더해준다. 135. 이를 2진수로.
10000111 가 될테고 결과를 지수부에 채운다.
#include <iomanip>
cout << setprecision(17);
double d = 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 << d << endl; // 1
cout << d2 << endl; // 0.99999999999999999
왜 1 로 떨어지지 않을까.
아무래도 0.1에 최대한 가까운 수로 만들어서 더하기 때문이다. 2진법으로 표현하기 때문.
둘이 같은지 물어보면 당연히 false 가 나올 것이다.
어느정도의 오차를 감안하고 맞는지 체크하면 좋다.
이때 사용하는것이 epsilon
if (abs(d - d2) < DBL_EPSILON)
cout << "이정도면 일치한다고 쳐 주자." << endl;
else
cout << "안돼. 이 차이라면 다르다." << endl;
일치한다고 나온다.
d 를 1.01 로만 바꿔줘도 다르다고 나오는 것을 확인 할 수 있다.
double d = 1.000000000000001; 까지도 다르다고 나오네. // 소수점 15개