전공/디지털 논리

[컴퓨터 구조] 부동 소수점의 표현

뜨거운 개발자 2023. 2. 10. 10:26

시작하며…

이전 게시물에서는 숫자의 양수음수 표현법에 대해서 다뤘다.

만약 2의 보수표현법에 대한 개념이 없다면 이전 글을 보고 오길 바란다.

이번에는 숫자를 컴퓨터로 나타내는데 문제가 되는 소수점에 대한 문제에 대해서 이야기 해보고자 한다.

우리는 아주 큰 숫자를 표현할 때 활용하는 방법을 사용할 수가 있다.

부동 소수점이란?

예를 들어 125000000000000000000 같은 숫자를 표현한다고 하자 이런 큰 숫자를 표현할 때 우리는 이렇게 쭉 나열하기도 하지만 그렇게 하는 것 보다는 1.25 * 10^20 이렇게 표현을 할 수가 있다.

위 방법과 같이 소수점을 적절히 이동시켜서 아주 큰 숫자 또는 아주 작은 숫자를 효과적으로 표현할 수 있게 하는 방법을 우리는 부동소수점 숫자 표현방법이라고 부른다.

그리고 위와 같은 방법으로 표현 된 숫자를 부동 소수점 수라고 부른다.

부동소수점 숫자의 표현은 수식으로 표현하는게 이해하기가 쉽다. 하지만 수식만 보면 머리가 헤롱거리는 여러분을 위해 설명을 추가해보겠다.

부동소수점 일반식

그림은 일반적인 32비트 부동소수점 표현형식이다.(C언어에서 float형식)

네 그냥 보면 뭔지 모르시겠죠..! 만약 설명이 필요없이 이 식과 그림을 보고 이해하셨다면 아주 훌륭합니다.

1.25 * 10^20 이런식으로 표현했잖아요?

M은 1.25가 B는 10, E는 20 S 는 0이됩니다.

일단 S는 부호비트인 것은 설명하지 않아도 알겠죠?

다음으로 이해하셔야 하는게 B인데 B는 2진수면 2, 10진수면 10 이렇게 표현하고자 하는 숫자의 지수입니다.

저희가 사용하는 컴퓨터는 대부분 2진수 이므로 B는 2로 고정해주세요!!

이제 E 는 뭔지 아시겠죠? 2의 몇 제곱인지를 표현해주는 지수입니다.(표현할 수 있는 숫자의 범위를 나타냅니다.)

그 다음으로는 M 즉 가수필드입니다. 여기서 가수는 숫자를 의미하는데 여기의 비트수가 많을수록 숫자의 정밀도가 높아질 수가 있습니다

결국 숫자의 표현범위가 넓으면 정밀도가 떨어지고, 숫자의 정밀도가 높으면 표현범위가 좁아지는 관계를 가지고 있습니다.

이제 일반적인 숫자를 어떻게 부동 소수점으로 나타낼 수 있는지 예시를 보면서 설명해보겠습니다.

정규화된 표현

부동 소수점 표현에서 한가지 숫자에 대해서 여러가지의 표현이 존재 할 수가 있다.

예를 들어서

  • 0.1101 * 2^5
  • 11.01 *2^3
  • 0.001101 * 2^7

이 세가지 숫자는 모두 같은 값을 나타낸다.

따라서 우리는 혼란을 막기위해서 정규화된 표현으로 나타냅니다.

정규화된 표현이란 : 소수점 우측의 첫 번째 비트가 1이 되도록 지수를 조정하여 표현한 보동소수점 수

따라서 위의 예시에서 정규화된 표현은 0.1101 *2^5 이 됩니다.

여기서는 이렇게 표현했지만 실제 부동 소수점 표현법에서는 1.101 * 2^4 이렇게 표현하고 1을 버리는 것 같다.

정규화된 수를 부동 소수점으로 표현 예시

0.1101 *2^5을 위에서 표현했던 부동소수점 방법으로 표현해보자.

일단 소수점 좌측에 있는 0은 저장할 필요가 없기 때문에 0.1101에서 1101만 넣어주면 된다. 이 형식대로 표현해보면

부호비트(S) : 0

지수(E) 필드 : [0000/0101]

가수필드(M) : [1101/0000/0000/0000/0000/000]

이렇게 됩니다.

이렇게만 생각하면 정말 간단한데 저희는 주어진 비트로 최대한 많은 숫자를 표현하고 싶기 때문에 한가지 공통적인 특징을 활용할 생각입니다.

바로 정규화된 표현에서 2진 소수점 아래의 첫번째 비트는 항상 1이되기 때문에 반드시 저장할 필요는 없다. 다만 나중에 계산을 할 때 그 비트가 있는 것처럼 처리해주면 되는 것이다. 이렇게 해주면 23비트 가수필드를 사용해서 소수점 아래 24번째 비트까지 저장할 수 있게된다.

0에 대한 부동소수점 표현

부동소수점. 표현에서 정수 0에대한 표현이 문제가 된다. 가수는 물론 0이 되어야하지만, 0*2^E=0이므로 지수는 어떤 수가 되고 상관이 없다.

그러나 프로그램이 실행될 때 0검사에서 데이터의 모든 비트들이 0이 아닌 경우를 검사과정이 복잡해진다. 그런 검사가 용이해지도록 하기 위해서는 모든 비트가 0이 되는 것이 바람직하다.

그런데 만약 E(지수)의 값이 음수로 아주 크다면 2^E의 절댓값이 거의 0에 가까워질 것이다. 이런 사실을 근거해서 제안된 방법이 바이어스된 숫자로 표현하는 것이다.

바이어스 된 숫자 표현

바이어스 된 수란 어떤수에 바이어스 값(특정 값)이 더해진 수를 말한다.

실제로 바이어스가 127 이라면 excess -127 이라고 부르고 128 이라면 excess -128이라고 부른다.

바이어스가 128인 경우에는 2를 표현할 때 [0000/0010]에서 128을 더해서 [1000/0010]이 됩니다.그리고 음수의 경우에는 -2 는 [1111/1110]에 128을 더해서 [0111/1110]이 됩니다.

반대로 바이어스된 숫자를 해석하는 방법은 128을 빼주기만 하면된다.

[1000/0001]이라는 숫자가 있다면 [0000/0001]으로 해석해서 지수는 2^1로 표현하는 것이다.

따라서 바이어스가 128인 경우 지수필드에 [0000/0000]이렇게 저장되어있는 경우는 2^ -128 이 되기 때문에 수의 크기는 아주 작다는 의미가 된다. 따라서 0을 표현하는데 더 어려움이 없어져서 0검사 문제를 해결 할 수가 있다.

실제 float 같은 경우 +127을 해주면 된다!!

 

 


Uploaded by

N2T
728x90