업데이트:

태그: , ,

카테고리:

부동소수점에 대한 이해

숫자는 컴퓨터 프로그램에서 가장 많이 사용되는 데이터타입니다.
가장 기초적이기에 사람들은 그것들에 대해 충분한 시간을 들여 이야기하지 않는다.
많은 사람들이 프로그램에서 숫자를 사용하는 방법을 알고 있으나,
프로그래밍을 하면 단순히 눈에 보이는 것 이상을 알 수 있다.


컴퓨터가 실수를 표현하는 방식

부동소수점은 실수를 표현하는 방식이므로, 컴퓨터가 어떻게 실수를 표현하는지에 대해 먼저 알아야한다.

컴퓨터는 모든 데이터를 2진수로 표현하므로, 실수를 2진수로 표현하는 방법은 복잡하다.
현재 사용되는 실수 표현 방식은,

  1. 고정 소수점 방식
  2. 부동 소수점 방식

이 있다.


고정소수점(fixed point)

고정 소수점 방식은 실수를 정수부, 소수부로 나누어 표현한다.
32비트 실수(4바이트 실수)는

Screen Shot 2022-07-12 at 4 37 01 PM

위 처럼 부호 1bit, 정수부 15bit, 소수부 16bit으로 고정되어 있다.


부동소수점(floating point)

고정소수점 방식처럼 정수부와 소수부로 실수를 나누는 것이 아닌,
가수부와 지수부로 실수를 표현할 수 있다.

Screen Shot 2022-07-12 at 4 39 04 PM

단, 컴퓨터는 데이터를 2진수로 저장하므로, 기수는 2로 고정되어있다.


정확도 (accuracy) vs 정밀도 (precision)

정확도

정확도는 목표값과 가까운 정도를, 정밀도는 측정을 반복했을때 측정 값들 간 가까운 정도를 의미한다.

정수 연산은 정확도(accuracy)를 가진다.
정수 2라는 값 자체가 2를 의미한다.
그리고 2에 1을 더하면 3이 되고, 3이라는 값 자체가 된다.
오버플로우가 일어나지 않는 한, 비트단위로 항상 원하는 답을 얻을 수 있다.

하지만 정수는 정밀도를 가지지는 못한다.

5와 4를 2로 나눈다면 둘 다 결과는 2가된다.
결국 5가 4보다 더 큰 정보는 유실되고 만다.



정밀도

부동소수점은 정수와는 반대 포지션을 가지고 있다.
부동소수점들은 위의 정수들이 놓치는 정보를 유실하지 않기에 대게 좋은 정밀도를 가지고 있다.
충분한 비트만 있다면 원래 수에 가까운 수를 얻을 수 있다.

하지만 부동소수점들은 정확도가 낮다.

1/3 이라는 숫자를 표현하고 싶더라도, 유한 10진수 표현으로는 절대로 이 무한소수를 표현할수 없다.
어떤 작업을 하든, 정확하게 변수로 표현할 수 없을 가능성이 높다.
그래도 부동소수점이 고정소수점에 비해 유용하기에 이런 오류를 바로잡아주기만 하면 된다.



부동소수점 표현방식

부동소수점 표현방식은 기계마다 다르지만, 오늘날에는 IEEE-754표준을 따른다.
이 표준은 살펴볼 가치가 있다.


IEEE-754의 flaot(4bytes)double(8bytes)에는 3가지 구성요소가 있다.

  1. sign - 1bit의 부호부
  2. exponent(지수) - 크기순서를 나타낸다.
  3. mantissa(가수) - 숫자의 실제 자릿수를 결정

bit layout으로 나타내보면,

 seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm 
31                              0

이렇게 나타난다.

예를 들어, -118.625를 이진법으로 나타내면

11110110.101

이 되는데, 이때 소수점을 왼쪽으로 이동시켜 왼쪽에 1만 남도록한다.

1.1110110101 * 2^6

소수점 오른쪽 부분인 가수부는 23bit를 채우기위해 0으로 채운다.

11101101010000000000...

지수6을 정보에 나타내기 위해서 Bias + 6을한다.
32bit IEE754에선 Bias가 127이므로 6 + 127 = 133을 이진법으로 변환해 exponent에 저장한다.
이진법으론 100000101이다.

1|10000101|11011010100000000000...

이렇게 이진수를 통해 고정소수점을 나타낼 수 있는데, double(배정밀도)의 경우에는 64bit중 부호 1bit, 지수부 11bit, 가수부 52bit이다.



고정소수점 표현방식

실수를 이진수로 바꿔 그대로 데이터에 저장한다.
가령, -118.625가 있다면,

1|1110110|0.625|

0.625를 이진수로 만들기 위해선 2를 곱한 정수부를 비트로 취하고, 버려나가면된다.

0.625 * 2 = 1.250 => 1
0.250 * 2 = 0.5   => 0
0.5   * 2 = 1     => 1

따라서 -118.625는

1|1110110|101

이 된다. 이제 데이터 크기에 맞게 나머지 bit를 채워줘야하는데, 정수부와 소수부를 나누는 fractional bits를 미리 정해놓아야하고,
이때 정수부는 왼쪽부터 0을, 소수부는 오른쪽부터 0을 채워나가야한다.

float자료형에서 fractional bits가 8개일때

1|00000000000000001110110|10100000

이렇게 만들어진다.



따라서 -118.625는
부동소수점하에서
1|10000101|11011010100000000000000

고정소수점하에서
1|00000000000000001110110|10100000

Fixed-Point Number 컴퓨터에서 실수 표현 소수점을 이진수로 부동 소수점 수

댓글남기기