부동 소수점은 실수의 표현과 아주 작은 수와 아주 큰수를 표현하기 위해 도입되었습니다.
또한 고정 소수점이라는 방식도 존재하며 우선 고정 소수점 부터 무엇인지 알아봅시다.
고정 소수점(Fixed Point)
소수점이 찍힐 위치를 미리 정해놓고 소수를 표현하는 방식입니다.
- 장점: 실수를 정수부와 소수부로 표현하여 단순합니다.
- 단점: 표현의 범위가 너무 적어서 활용하기 힘듭니다. (정수부는 15bit, 소수부는 16bit )
- 정수부만 따졌을때 2^16 - 1 의 수 까지 표현이 가능한데, 터무니 없이 작은 수 입니다.
부동 소수점
지수의 값에 따라 소수점이 움직이는 방식을 활용한 실수 표현 방법입니다.
즉, 소수점의 위치가 고정되어 있지 않습니다.
실수를 가수부 + 지수부로 표현합니다.
- 가수: 실수의 실제값 표현
- 지수: 크기를 표현
- 장점: 표현할 수 있는 수의 범위가 넓어집니다. (현재 대부분 시스템에서 활용 중)
- 단점: 오차가 발생할 수 있습니다. (부동 소수점으로 표현할 수 있는 방법이 매우 다양함)
정규화
부동소수점의 수 표현에서는 어느 한 수에 대해 여러개의 표현이 존재할 수 있습니다. 아래의 값들은 모두 같은 값을 나타냅니다.
위와 같은 혼란을 막기위해 정수부의 1만 남기도록 소수점을 이동하고 소수점에 관한 정보는 2^n 으로 표현합니다.
다음 예시처럼 말이죠.
5.75를 예로 들면 다음과 같은 IEEE754 32bit 표준을 얻을 수 있습니다.
이때 1.XXX의 1은 항상있기때문에 비트에 할당하지 않고 나머지 XXX만 가수 비트에 순서대로 놓입니다.
그렇다면 만약 지수가 음수라면 2의 보수표현으로 지수부를 표현할까요?
바이어스 표현법 (Bias)
바이어스 표현법을 사용하여 unsigned로 지수를 표현할 수 있습니다.
이로써 얻을 수 있는 이점은 값을 비교할 때 지수의 크기만으로 대소 비교를 할 수 있다는 것입니다.
가수가 아무리 크더라도 지수가 큰 수가 큰수이고 , 바이어스로 unsigned를 사용해 지수표현을 했으므로 만약 2의 보수법을 사용했더라면 발생했을 불필요한 연산 또한 줄어들게 됩니다.
바이어스 값은 어떻게 구하나?
바이어스를 구하는 공식은 2^(지수비트 - 1) -1 입니다.
따라서 IEEE 754 32비트 표준의 바이어스 값은 127이 됩니다.
공부를 하면서 왜 바이어스 값이 127일까? 가 궁금했습니다.
질문과 검색을 통해 얻은 결론은 8비트이기때문에 [0, 255] 까지 256 가지의 표현이 가능하고, 이때 0 과 255 는 각각 0 , (INF, NAN)의 Special Value 이므로 실제로 사용하는 254 가지중 절반인 127 이 바이어스 값이 된다라고 생각하게 되었습니다.
바이어스 표현법 예시
이론을 알아보았으니 실제 어떻게 사용되는지 알아봅시다.
지수부를 2의 보수로 표현한 값 + 바이어스 값
-9.6875를 예시로 들어보겠습니다. 이를 정규화 할 경우 [부호부 음수, 지수부 3, 가수부 0011011] 가 됩니다.
* 왜 -9.6875 가 [지수부 3, 가수부 001011] 가 될까 ?
-9.6875는 -1001.1011(2) 이기 때문이다. 이를 소수점자리를 옮기면 -1.0011011 * 2³ 이 된다.
0000 0011 + 0111 1111 = 1000 0010 이기때문에 다음과 같은 비트가 됩니다.
그리고 이렇게 바이어스로 표현된 지수부의 값에 따라 Normalized value, Denormalized value, Special value로 구분할 수 있습니다.
Normalized value
지수부가 1 또는 0 으로만 채워져 있는 경우가 아니라면 Normalized value 라고 할 수 있습니다.
Denormalized value
Denormalized value는 지수부가 0으로 채워져 있는 경우를 표현합니다.
그러면 0의 표현은 어떻게 할까요?
상식적으로 생각하면 0은 표현할 수 있는 가장 작은 양수 보다 작거나 같아야 합니다. 부동 소수점에서 표현할 수 있는 가장 작은 수는 다음과 같습니다.
따라서 모든 비트가 0인 경우를 0이라고 정의합니다.
32비트 float가 표현할 수 있는 가장 작은 수
0을 제외한 양수 중 표현할 수 있는 가장 작은수는 2^-149 입니다. 지수부가 모두 0으로 채워졌을 때 -127 승을 가지는데 어떻게 2^-127승 보다 더 작은 수를 표현할 수 있는 것일까요?
지수부가 모두 0 인 경우는 특별한 경우로 나누어 생각해야합니다.
모든 비트가 0인 경우는 0을 나타냅니다. (위에서 살펴보았듯이)
지수부의 비트가 0이지만 가수부의 비트는 0이 아닌 경우 , 유효수에서 정수값을 1이 아닌 0으로 해야합니다. 그리고 지수값을 -126으로 약속합니다. 기존의 정규화에 어긋나기 때문에 Denormalized 라고 합니다.
예를 들어, 정수부가 0이 되기때문에
0.10000000000000000000000 * 2^-126 = 2^-127 를 표현할 수 있고
다음처럼,
0.00000000000000000000001 * 2^-126 = 2^-149를 표현할 수 있게 됩니다.
따라서 0을 제외한 양수 중 표현할 수 있는 가장 작은수는 2^-149 가 됩니다.
참고로 2^-126 은 다음과 같습니다.
1.00000000000000000000000 * 2^-126 = 2^-126
Special value
지수부 비트가 모두 1로 채워진 경우
우선 이 경우 지수부는 128을 나타냅니다. 하지만 가수부의 형태에 따라서 두 가지 상태로 나뉩니다.
- 가수부 비트가 모두 1인 경우 INF 를 나타냄 (무한)
- 가수부 비트가 모두 1이 아닌 경우 NAN 을 나타냄 (미정값)
지수부 비트가 모두 0로 채워진 경우
이 경우 0 값을 나타냅니다.
최대값
Ox7F7FFFFF 는 float 자료형이 표현할 수 있는 가장 큰 수 입니다.
부동소수점 표현의 한계
앞서 공부했듯이 부동소수점을 통해 표현할 수 있는 수의 범위가 넓어졌지만 한계점도 존재합니다.
지수가 충분히 클 경우
만일 지수부가 23을 나타낸다고 할때, 가수부가 어떤 비트로 채워져있건 상관없이 소수점이 오른쪽으로 23자리를 이동하게 되므로 더 이상 소수점 이하 부분이 남아있지 않게 됩니다. 이것은 지수부가 23이상 일 경우에는 더 이상 float로 소수점 이하를 표현할 수 없다는 의미가 됩니다. 즉, 정수만을 표현할 수 있습니다. 실제로 그림에서 가수부가 모두 0일 경우를 계산하면 float가 나타내는 값은 10진수로 8,388,608이 되며, 즉 float로 8,388,608이상을 나타낼 때는 더 이상 소수점 이하를 표현할 수 없다는 것이 됩니다.
참고자료
1. https://dataonair.or.kr/db-tech-reference/d-lounge/expert-column/?mod=document&uid=52381
2. https://thrillfighter.tistory.com/349
5. https://sudo-minz.tistory.com/7
6. https://minimin2.tistory.com/125
'CS > 컴퓨터구조' 카테고리의 다른 글
패리티 비트 & 해밍 코드 (0) | 2023.04.04 |
---|---|
CPU의 구조와 기능 (0) | 2023.04.04 |
컴퓨터 시스템의 개요 (0) | 2023.04.03 |
캐시 메모리의 쓰기 정책 / 버퍼와 캐시의 차이 (0) | 2023.04.02 |
캐시 메모리 (2) | 2023.04.01 |