[C++] Float의 메모리 구조
0. Float의 메모리 구조
float의 메모리 구조는 IEEE 754 표준을 따르고, 총 32비트로 구성되어 있다.
부호(Sign) 1비트 / 지수(Exponent) 8비트 / 가수(Mantissa/Fraction) 23비트
1. Sign, Exponent, Mantissa
1-1. Sign
0이면 양수, 1이면 음수
1-2. Exponent
- 8비트
- Bias 127을 기준으로 저장됨
- ex. 실제 지수가 3이면 저장값은 127 + 3 = 130(
10000010
)
1-2-1. bias를 사용하는 이유
소수점 아래의 작은 값(ex. 2^-3, 2^-5 등)을 표현하려면 음수 지수가 필요하다. 지수부에서 부호 비트를 따로 사용하려면 그만큼 표현 범위가 더 줄어들기 때문에, 이를 위해 bias를 사용한다. 실제 지수가 -3이어도, 저장 값은 -3 + 127 = 124 이기 때문에 부호 비트를 따로 할당할 필요 없이, 항상 양수값으로 저장할 수 있다. 값을 해석할 때는 127을 빼서 실제 지수를 사용한다.
1-3. Mantissa
- 23비트
- 정규화된 형태로 저장됨
- 1.xxxxxx 형태에서 1.은 생략하고 xxxxxx만 저장됨
- 실제 계산 시에는 생략된 1.을 앞에 붙임
1-3-1. 소수 부분을 2진수로 변환하는 법
0.75
를 2진수로 바꾸는 예시를 보자.
0.75 x 2 = 1.5 -> 정수 1
0.5 x 2 = 1.0 -> 정수 1
0.0 -> 끝
즉, 소수 0.75
는 2진수로 0.11
이다.
(정수비트 왼쪽부터 오른쪽으로 올 수록 나누기 2만큼 작은 값이 된다. 소수부도 마찬가지로 0.5, 0.25, 0.125, … 식으로 계속되는 방식이다.)
그런데, 이번엔 0.33
을 2진수로 바꿔 보자.
- 0.33 x 2 = 0.66 -> 정수 0
- 0.66 x 2 = 1.32 -> 정수 1
- 0.32 x 2 = 0.64 -> 정수 0
- 0.64 x 2 = 1.28 -> 정수 1
- 0.28 x 2 = 0.56 -> 정수 0
- …
무한히 반복되기 때문에 0.33은 이진수로 정확히 표현할 수 없다. 이런 상황이 바로 float에서 오차가 생기는 대표적인 예시다.
2. 예시
1.5의 저장 구조
Sign
: 01.5
는 2진수로1.1
이므로, 정규화하면1.1 x 2^0
- 따라서,
Exponent
= 0 + 127 = 127 ->01111111
- Mantissa =
.1
->100000...
Leave a comment