0.1 + 0.2 != 0.3 (작성중)
어제 velog를 읽다가 글 하나를 발견했다
아아아닛 !
머리가 띵했다.
그래서 구글신님에게 물어봤는데
부동소수점표현 때문에 그렇단다.
사실 대학교에서 배운건데 까먹어 버린것이다.
그래서 오늘은 부동소수점에 대해서 살펴볼 것.
아래 적는 내용은 내가 까먹을 수 있는 부분에 대해서만 써놓은것이다.
1. 단정도(32bit)와 배정도(64bit) 부동소수점 표현
먼저 둘다 공통적으로 1비트를 부호로 사용하고
단정도의 지수는 8비트, 배정도는 11비트
가수는 단정도에서 23비트, 배정도에서는 52비트가 된다.
2-1. 지수부의 쓰임새
0.2 는 부동소수점표현으로 0.0011001100110011... 이다.
하지만 저장할때는 가장 앞에있는 1을 찾아서 그 뒤로 소수점을 옮겨준다.
예를들면 0.2는 1.10011001100110011... * 2^-3
4.5는 100.1에서 1.001 * 2^2이 되는것이다.
그래서 지수부는 2^-3과 2^2에서 -3과 2같은 지수를 저장하는 공간이다.
그러면 소수의 표현 범위가 대단히 넓어진다! (뇌피셜)
그리고 가장 앞에있는 1은 버린다.
왜냐? 지수는 가장 앞에있는 1을 기준으로 만들어서 때도 상관없을 뿐더러
최소 한개의 비트를 더 확보할수 있는 이유 아닐까?(뇌피셜)
2-2. bias
지수부에 지수를 저장하는데에는 bias가 있다.
나는 평소 bias란 용어에 대해 자세하게 생각해 본적이 없다.
어디서 본건지 기억도 안난다.
bias 단어 자체의 뜻은 편견, 성향이라는 뜻이다.
그냥 default랑 비슷한 무언가라고 생각하겠다.
그래서 bias는 단정도(32bit)에서 127, 배정도(64bit)에서 1023인데
bias에서 숫자가 올라간만큼 양수지수고 내려간만큼 음수지수다
지수 -3은 단정도에서 127 - 3이 되어 124
즉, 01111100이 된다.
지수 2는 단정도에서 127 + 2가 되어 129
이는 10000001이 된다.
그래서 이렇게 지수부로 입력이 된다.
3. 그래서 왜 0.1 + 0.2 != 0.3이 되는건가?
단순하다.
2진법으로 소수를 저장하면
1/2, 1/4, 1/8, 1/16 ...
이 되기에 0.1, 0.2같은 소수는 2진법으로 무한소수가 된다!
그래서 가수부에 저장하기 위해 반올림을 해야하는데
0.1과 0.2가 각자 반올림 된 수가 더해지고 그 더해진 수에서 한번 더 반올림이 이루어진다.
0.1 + 0.2는 총 세번의 반올림이 이루어진다!
그에 반해 0.3은 한번 뿐이므로 결과가 다를 수 밖에 없다.
다음에 내용이 더 생각나면 글을 더 써보겟다