이 글은 제가 과거에 운영했던 사이트인 http://dotnet.mkexdev.net 의 글을 옮겨온 것입니다.
그 전에 운영했었던 사이트(mkex.pe.kr)은 흔적도 없이 사라 졌습니다. 그속의 글들도 모두...
그래서 이 사이트도 사라지기 전에 옮기고 싶은 글을 조금씩 이 블로그로 이동시키려 합니다.
(원본글) http://dotnet.mkexdev.net/Article/Content.aspx?parentCategoryID=2&categoryID=9&ID=99
---
앞에서 부동 소수점 방식에 대해 간략히 알아 봤습니다. 보통 프로그래밍 언어에서 실수형 데이터를 저장하기 위해
두가지 데이터 타입을 둡니다. float 와 double 이지요..
float : 단정도 부동 소수 (32비트)
double : 배정도 부동 소수 (64비트)
데이터를 표현하는데 사용되는 비트수가 다르기 때문에 당연히 표현가능한 수의 범위가 달라집니다.
컴퓨터는 실수형 데이터를 표현하기 위해 할당되어진 비트들 중 특정 비트를 지수,가수,부호로 사용함으로써
실수를 표현합니다. 이 두 형식 모두 앞서 살펴본 (아래의)부동 소수 표현식으로 표현됩니다.
+- m * n의 e승
+- : 부호
m : 가수
n : 기수
e : 지수
아래의 그림은 배,단정도 부동소수 저장시 사용되어 지는 메모리 구조 입니다.
1) 단정도 부동 소수의 메모리 구조(32 비트 사용)
2) 배정도 부동 소수의 메모리 구조(64 비트 사용)
앞서, 우리는 위 표현식이 엄밀히 말하면 아래와 같다고 했습니다.
+- 1.m * 2의 e-127승
이유를 하나하나 살펴 봅니다.
[1] 기수는 2 이다
컴퓨터는 2진수를 사용하기 때문에 기수는 2가 되어 아래의 표현식으로 됩니다
+- m * 2의 e승
[2] 지수부는 excess 표현이 사용된다
지수부 역시 양수와 음수를 가져야 합니다.
10진수의 부동소수 표현에서 10의 지수 값으로 소수점의 위치가 변동 됨을 알 수 있습니다. 이는 2진수도 마찬가지
입니다. 즉, 지수부의 값이 - (마이너스) 가 되어야 할 필요가 있다는 말입니다. 그러나 지수부를 위한 메모리 공간에
는 별도의 부호 비트는 없습니다. 따라서 특별한 규칙을 만들어 마이너스를 표현하는데요...
이때 사용되는 것이 excess 표현입니다.
excess 표현은 지수부에서 나타낼 수 있는 최대 값을 반으로 나누어 그 값을 0 으로 보고
그것(0)보다 큰 값을 양수처럼, 작은값을 음수로 계산하는 것입니다.
(즉 최대값을 반으로 나눈 값을 기준으로 본다는 말이 됩니다)
한가지 예를 들어 보겠습니다.
단정도 부동소수인 float 에서 지수부를 위한 메모리 공간은 8비트 입니다.
8비트로 표현할 수 있는 최대 수는 11111111 이므로 10진수로 255 가 됩니다.
255 / 2 = 127.5 가 됩니다. 여기서 소수점 0.5는 버립니다.
즉 127을 0으로 취급합니다.
이때 지수부의 실제 값이 128이면 excess표현으로 인한 지수의 값은 1 이 되는 셈입니다
따라서 지수부의 값은 e-127 이 되느 것입니다.
+- m * 2의 e-127승
[3] 가수부는 특정 규칙을 사용하는 정규 표현을 사용한다
부동소수는 이미 알아본 바와 같이 다양한 형태로 표현될 수 있습니다.
10진수로 예를 들면 고정 소수 0.12 를 표현하기 위한 부동 소수는 아래와 같이 다양합니다.
0.12 = 0.12 * 10의 0승
0.12 = 12 * 10의 -2승
0.12 = 0.012 * 10의 1승
이와 같이 같은 수에 대한 표현방법이 다양하다면, 컴퓨터로 처리하기가 어려워 집니다. 따라서 특정한 표현방식
하나만 정해서 사용합니다. 위의 0.12 를 아래와 같이 하나의 표현 방식만 사용한다고 정해 둔다는 것입니다.
'소수점 이상은 0으로 하고, 소수점 이하 첫번째 자리는 0이 아닌 값으로 한다'
위의 규칙대로라면 0.12의 부동 소수 표현은 0.12 = 12 * 10의-2승 .. 이것만 가능 합니다.
이와 같이 특정 규칙을 정해 그 규칙대로만 표현하는 것을 정규 표현이라 합니다. 컴퓨터에서 2진수로 표현하는 부동소수 표현 방식에 이와 같은 규칙이 있습니다. '소수점 이상을 1로 고정한다' 라는 정규 표현을 사용합니다.
즉 반드시 정수부의 첫번째 자리는 1로 만들고 그 이상의 자리는 0으로 해주는 표현방법입니다.
소수점 이상을 1로 고정 하기 위해 2진수의 쉬프트 연산이 일어납니다. 또한 이렇게 고정한 1은 가수부의 표현
비트내에 포함시키지 않습니다. 정수부의 첫번째 자리는 반드시 1이라고 규칙을 정해 놓았기 때문에 별도의
비트가 필요치 않으며 가수부 비트내에 포함시키기 않음으로써 조금 더 넓은 범위의 수를 표현할 수 있게 됩니다.
(단정도 부동소수의 경우 23비트로 가수부를 표현하는데 첫번째 자리 1이 생략되었다고 할 수 있으므로 총 24비트
를 사용한다고 할 수 있을 것입니다)
아래는 단정도 부동 소수에서 가수부의 정규 표현을 사용하여 표현한 것입니다.
1011.0011 <- 원래의 숫자
0001.0110011 <- 정수부의 첫번째 자리가 1이 되도록 오른쪽 쉬프트
0001.01100110000000000000000 <- 소수점 이하를 23비트로 만듦
01100110000000000000000 <- 소수점 이하만 뽑아 정규 표현을 완료
Example>>
2진수로 표현된 실수(단정도 부동소수)가 아래와 같다고 할때 10진수로 변환하면...?
0 01111110 10000000000000000000
부호 지수부 가수부
1) 부호비트가 0 이므로 양수입니다.
2) 지수부의 값이 126 이므로 (127 - 126) = -1 , 즉 2의 -1 승 , 0.5가 됩니다.
3) 가수부의 소수점 이상 첫번째 자리가 1이므로
위의 가수부의 값은 1.10000000000000000000000 이 됩니다.
즉 10진수로 1.5가 됩니다.
결론)
+- m * 2의 e승
이 표현식에 대입해 보면 + 1.5 * 0.5 = 0.75 가 됩니다
'SW개발' 카테고리의 다른 글
비트(bit) 단위 연산 (0) | 2023.10.27 |
---|---|
실수 연산, 어떻게 하시나요??? (0) | 2023.09.27 |
실수 데이터의 표현 방식 - 부동소수점 방식 (0) | 2023.09.27 |
0.1 을 100 번 더해도 10이 되지 않는다? (0) | 2023.09.27 |
정수 데이터의 표현 방식 (0) | 2023.09.27 |