본문 바로가기
웹(web)

소수점을 표현하는 방법

by 바코94 2024. 5. 8.

 

1) 이진기수법

인간은 기본적으로 10진법을 사용하지만, 컴퓨터가 이해할 수 있는 숫자는 0과 1 뿐이다. 컴퓨터는 숫자와 문자, 이미지와 같은 데이터를 0과 1 만을 사용하여 저장한다. 0과 1을 사용하는 방법을 2진법이라 부른다.

따라서, 컴퓨터에서 소수점을 다루는 방법을 알려면 10진수로 표현된 소수점을 2진수로 어떻게 표현하는지 알아야한다.

일단 소수점 앞부분은 기존 정수를 변환하는 방법과 동일하다. 

소수점 뒤에 있는 숫자들을 하나씩 2진수로 바꿔버리는 방법을 생각해볼 수 있지만 그렇게 하면 아래 예시처럼 서로 다른 10진수 숫자가 2진수로 변환되었을 때 같아지는 문제가 있다.
잘못된 변환 방법 예시) 변환된 2진수가 같아짐
0.9 -> 0.1001
0.41 -> 0.100 1

소수점 뒤에 숫자는 정수부에서 변환하던 것에서 정반대로 하면 된다. 즉 정수부에선 10진수를 2로 나눠가면서 1이나 0을 뽑았다면 소수부는 10진수에 2를 곱해가면서 1이나 0을 뽑아낸다. 그리고 정수부 변환할 때는 1이 나오면 종료했다면 여기서는 0이 나오면 종료하고, 결과를 밑에서부터가 아니라 위에서부터 읽어준다.

0.75를 이진수로 변환하는 예시를 보자.

0.75 * 2 = 1.5 -> 1을 뽑고 나머지 0.5
0.5 * 2 = 1.0 -> 1을 뽑고 나머지 0

나머지 0이 나왔으니 변환을 종료하고 빼낸 숫자들을 위에서부터 읽어주면 된다. 즉 0.75(10) -> 0.11(2)이 된다.

   0.11(2) = 1×2^(-1) + 1×2^(-2)
            = 0.5 + 0.25
            = 0.75

 

2) 고정소수점 (Fixed Point) 표현 방식

설명한 방법대로 10진수를 2진수로 바꾼 값을 그대로 정수부와 소수부에 사용하는 방식이다.
예를 들면 7.625라는 실수는 2진수로 변환하면 111.101이다.

16비트 체계를 쓴다고 가정하자.
부호비트: 맨 앞 1자리는 0이면 양수, 1이면 음수라는 뜻
나머지 비트들은 소수점을 기준으로 정수부랑 소수부를 표현하는 비트로 각각 나누어 사용. 소수점의 위치는 미리 정해둔다.
소수부의 경우 앞에서부터 채우며 남는 뒷자리는 다 0으로 채운다.
이러한 고정소수점 방식은 구현하기 편리하고 오차 없이 정확하다. 사용하는 비트 수 대비 표현 가능한 수의 범위 또는 정밀도가 낮은 편이다.

3) 부동소수점 (Floating Point) 표현 방식

부동소수점 표현 방식에서는 2진수로 변환한 결과를 몇 가지 과정을 추가로 거친다.

- 정규화 (Normalization)

여기서 정규화는2진수를 다음 꼴로 변환하는 것을 말한다.
1.xxx * 2^n

변환하는 방법은 간단한데, 정수부에 1만 남을 때까지 소수점을 왼쪽으로 옮기고 옮긴 칸 수만큼 n 자리에 집어넣으면 된다.

예를 들어서 위에서 봤던 111.101을 정규화하면 1.11101 * 2^2가 된다.(2칸 옮겼기 때문)

여기서 소수점을 '이동' 시킨다는 데서 floating point라는 용어가 사용되었으리라 생각된다.

- IEEE 754 부동소수점 표현

IEEE 754  따르면 부동소수점 방식으로 실수를 저장하는 데는 32(또는 64)비트가 사용된다. 32비트 기준으로는 아래와 같은 구조를 가진다.

부호 비트: 0이면 양수, 1이면 음수
가수부: 정규화 결과 1.xx 에서 xx 부분 숫자들을 왼쪽부터 넣는다. 남는 부분은 0으로 채운다.
지수부: 2^n의 n(지수)에서 bias 값을 더한 값을 사용한다. 더한 결과를 2진수로 변환하여 넣는다.

IEEE 754에서 32비트를 쓰는 경우 bias는 127이라고 규정하고 있다. 따라서 2 + 127 = 129를 2진수로 바꾼 10000001(2)이 들어간다.

결론적으로 7.625는 컴퓨터에서 아래와 같이 저장된다.

bias를 쓰는 이유는, 지수가 음수인 경우를 위해서 있다.

예를 들면 0.000101(2)가 있을 때, 정규화를 위해 정수부를 1로 만들어야 한다고 했다. 그러니까 소수점을 오른쪽으로 밀어서 1.01(2) * 2^-4가 된다.(소수점이 네 칸 이동)

지수용 부호 비트를 사용하지는 않고, 8비트를 가지고 음수와 양수를 둘 다 표현하기 위해 0~127(10) 구간은 음수, 128~255(10) 구간은 양수를 표현하도록 만든 것이다.

(참고: 실제로 0, 255는 0이나 0에 한없이 수렴하는 작은 수들, 무한대, NaN(Not a Number) 등을 표현하기 위해서 특별하게 지정되어 있기 때문에 일반적인 표현 범위에 포함되지 않으며, 저런 수들을 표현할 때는 이 글에서 설명한 정규화 방법이 적용되지 않는다)

위 그림에서 살펴본 32비트 체계를 32비트 단정도 (Single-Precision), 64비트 체계를 64비트 배정도 (Double-Precision) 이라고 부른다. 

프로그래밍 언어에서 흔히 접할 수 있는 실수형 타입 float, double이 각각 전자, 후자에 해당한다. 

64비트 체계에서는 지수부가 11비트, 가수부가 52비트다. 지수부가 2^11 즉 2048개의 수를 표현할 수 있으므로 0~1023 구간은 음수, 1024~2047 구간은 양수 지수를 의미하며 bias는 1023이 된다.

이와 같은 부동소수점 표현 방식은 위에서 살펴본 고정소수점 표현 방식에 비해서 비트 수 대비 표현 가능한 수의 범위와 정밀도 측면에서 보다 유리하다.

 

'웹(web)' 카테고리의 다른 글

브라우저 이벤트루프  (0) 2024.10.04
웹 어플리케이션 성능 최적화  (0) 2024.06.15
csrf 이란  (0) 2024.05.02
springboot hot reload 방법 참고 링크  (0) 2024.03.08
크롬을 이용한 프론트엔드 디버깅  (0) 2022.04.22