고정소수점과 부동소수점
고정소수점과 부동소수점이라는 개념이 있다. 이름만 봐서는 이 개념들이 왜 컴퓨터와 관련이 있는지 알기 힘들다.
컴퓨터는 0과 1로 이루어진 기계어를 사용한다. 우리가 숫자 혹은 문자를 입력해도, 컴퓨터는 0과 1의 조합으로 해당 문자를 인식한다.
우리는 기본적으로 10진법을 이용하지만 컴퓨터는 0과 1만 사용하는 2진법으로 이를 표현한다.
고정소수점과 부동소수점을 왜 알아야 하는가, 컴퓨터가 실수를 표현할 때 쓰는 방식이 바로 부동소수점이다.
고정소수점
정의
소수점이 찍힐 위치를 미리 정해놓고 소수를 표현하는 방식이다. (정수 + 소수)
고정소수점에서는 부호, 정수부, 소수부가 필요하다.
예를 들어, -3.141592는 부호(-)와 정수부(3), 소수부(0.141592) 로 이루어지는 식이다.
고정소수점 표현 방식의 장점은 직관적이라는 것이다. 실수를 정수부와 소수부로 단순하게 나누기 때문에 이해하기 쉽다.
그러나 단순한 만큼 그 표현의 범위가 너무 적어서 활용하기가 힘들다는 한계도 있다.
숫자를 하나 예로 들어보자. 9.99라는 숫자가 있다고 하면 어떨까.
2진수로 표현하게 되면 9.99는 다음과 같다.
0101.111111101011100001...
9는 2진수로 표현하면 101이 되고, 0.99를 2를 계속 곱해가면서 정수부가 나오면 숫자를 넣는 방식이다.
9.99와 같이 지저분한 숫자들은 좀 길어진다. 0.625같은 깔끔한 숫자의 경우는 간단하게 2진수로 0.101이 된다.
만약 8.625라는 실수가 있다면, (16비트 체계라는 전제하에) 00001000.10100000이 된다.
앞의 0은 부호, 2의 3승, 0.625를 2진수로 바꾸어 1000.101이 된다.
위의 예시에서 알 수 있듯이 부호 + 정수부가 8비트, 소수부가 8비트를 차지하고 정수부는 뒤에서부터 채우고 소수부는 앞에서부터 채운다.
부동소수점
정의
실수를 가수부 + 지수부로 표현한다.
부동소수점 표현방식에서는 2진수로 바꾼 후에 정규화 과정을 거친다.
1.xxxx... * 2^n 의 꼴로 만들기 위해 정수부에 1만 남을 때 까지 소수점을 이동시키고, 이동시킨 횟수만큼 n을 증가시킨다.
8.625 = 1000.101 = 1.101 * 2^3
IEEE (전기전자공학자 협회) 의 표준에 따르면 부동소수점 방식으로 실수를 저장하는 데는 32비트, 또는 64비트가 사용된다.
32비트를 기준으로 아래 사진과 같은 구조를 지니는데, 부호 비트는 0이면 양수, 1이면 음수로 고정소수점과 표현 방식이 같다.
이 때, 소수점의 왼쪽은 무조건 1이기때문에 표현하지 않는데, 이 때문에 hidden bit라고 부르기도 한다.
8.625 = 1000.101의 = 1.101 * 2^3의 예시에서, hidden bit를 제외한 101은 23자리 가수부에 왼쪽부터 채워 넣고 나머지는 0으로 채운다.
문제는 지수부인데, 2^3 에서 3을 그대로 넣는 것이 아니라, bias(IEEE 표준, 32비트 기준 127)을 더한 뒤, 2진수로 바꿔 넣어야한다.
3 + 127 = 130 = 10000010이 된다.
근데 대체 이 bias를 왜 사용하는가? 실수를 1.xxx로 정규화 하다보면 지수가 양수이면 좋겠지만 음수일 수도 있게 된다.
예를 들어, 이진수로 0.000101 을 정규화 하면 1.01 * 2^-4 가 된다.
이 때문에 8자리에 음수와 양수를 모두 표현하기 위해 0에서 127 구간은 음수, 128에서 255구간은 양수를 표현하도록 bias를 더하게 만든 것이다.
계산된 지수가 너무 커서 지수부에 표현될 수 없으면 overflow, 반대는 underflow가 발생한다.
'Computer Science' 카테고리의 다른 글
[TCP] 3 way handshake & 4 way handshake (0) | 2022.08.07 |
---|---|
트랜잭션 격리수준 (0) | 2022.07.31 |
Index (0) | 2022.07.24 |
Call by value, Call by reference, Call by assignment (0) | 2022.07.19 |
함수형 프로그래밍 (0) | 2022.07.18 |