※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


이번에는 Floating Point Number에 대해서 이야기 해보도록 하자.


왜 Floating인가? Floating의 원래의 의미는 떠다닌다는 의미이다. 떠다닌다 라는 것은 움직인다 정도로 해석하면 될 것 같다. 그렇다면 뭐가 움직인다는 것이냐? 이제부터 그것을 알아보자.


컴퓨터에서 소수를 표현하는 방법이 Floating Point Number이다. Floating Point Number는 부호, 지수(exponent), 가수(mentisa) 부분으로 설명할 수 있다. 그런데 컴퓨터에서 데이터를 표현할 때 비트수의 한계가 있다. 가령 최근의 컴퓨터는 대부분이 32비트이기 때문에 32비트 환경을 가정하고 말해보자.


32비트의 비트열을 컴퓨터는 다음과 같이 사용한다.





위와 같이 소수를 표현할 때 지수와 가수를 가지고 표현을 하면 하나의 숫자를 표현하기 때문에 한 숫자를 표현하는 여러가지 방법이 있다. 가령 0.1을 표현할 때 (우선은 10진수를 생각해보자)


0.1 = 1 x 10의 -1승

0.1 = 10 x 10의 -2승

...


하나의 소수를 표현하는데 무수히 많은 방법이 있다. 지수가 움직이면서 표현을 하니까 움직인다.. 떠다닌다.. Floating.. Floating Point Number라고 하는 것이 아닌가 싶다. 나는 이 부분을 공부할 때 이런 질문이 떠올랐다. 하나의 숫자를 여러 방법으로 표현한다면 컴퓨터 입장에서는 귀찮을 거 같다는 생각이다. 뭔가 체계화된 하나의 규칙이 있어야 할 것 같았다. 생각을 해보니까 컴퓨터에서 소수 하나를 표현하는 방법은 한 가지 밖에 안나오는 것 같다. 그 이유는 가수의 범위 때문이다. 가수는 고등학교 수학에서도 배웠듯이 1을 포함한 1과 2사이의 숫자이다. 하나의 소수를 표현할 때 가수의 범위가 정해져버리니까 당연히 지수부의 숫자는 하나밖에 올 수가 없다. 


가령 165.75를 컴퓨터가 이해하는 32비트 표현으로 바꿔보자.

165.75를 2진수로 바꾸면 10100101.11가 된다. 이 숫자를 지수와 가수 부분으로 나누어서 표현해보자. 


2의 0승 x 10100101.11

2의 1승 x 1010010.111

...

2의 7승 x 1.010010111


가수는 범위가 1과 1 사이라고 했으므로 저 많은 것들 중에 컴퓨터가 택하는 것은 하나이다.

2의 7승 x 1.010010111 가 되겠다.


그렇다면 이것을 정말 32비트로 표현해보자.


우선 부호비트는 0이 된다. (+는 0, -는 1)

지수의 8비트를 구할 때 새로운 개념 bias라는 것이 등장한다. bias를 왜 하는지는 조금 뒤에 설명하겠다. 우선은 그냥 그러려니 하자. bias를 구하는 식은 아래와 같다.


bias = 2의 (w-1)승 - 1

단, w는 비트 수


컴퓨터에서 지수부는 8비트로 표현되기 때문에 컴퓨터에서의 bias는 2의 (8-1)승 - 1 = 127 이 된다. 이 bias를 무조건 지수와 더해라. 궁금해하지 말고 더하자. 뒤에 다 설명할 예정이다.

따라서 7 + 127 = 134 = 10000110(2진수)가 된다.


마지막으로 가수부분이다. 가수는 1.010010111이다. 모든 가수는 1을 기본적으로 가지고 있기 떄문에 1은 무조건 있다고 치고, 그 뒤부터 23비트에 표현하게 된다. 따라서 01001011100..00 이 된다.


정리하면 이와 같다.

165.75 = 0 10000110 01001011100000000000000 (2진수)


여기서 지수부분을 보자. 지수부분이 00000001 과 11111110사이인가? 그렇다. 그러면 우리는 이 영역을 nomalized 영역이라고 부른다. 한마디로 노말한 실수를 표현하는 부분이라고 생각하자. 이 가수부가 00000000이 되면 우리는 denomalized 영역이라고 부른다. 이는 매우 작은 숫자들을 표현할 때 사용하는 방법이라고 생각하자. 만일 지수부가 11111111이 되면 무슨 뜻일까? 이는 무한대를 표현하는 방법이라고 한다.


※ denomalized 영역에서 bias를 계산할 때 예외가 있다. 보통은 컴퓨터가 표현하는 지수부에서 bias를 빼면 지수가 나온다. 그런데 denomalized 영역에서는 지수부가 00000000임에도 불구하고 1 - bias를 한다. 32비트 환경에서는 1 - 127 = -126 이다. 즉 32비트 환경에서의 denomalized 영역은 2의 -126승을 표현한다.


한 가지 재밌는 것을 소개해주려고 한다. 2진수 Floating Point Number 를 10진수로 바꿔주는 프로그램이다. 아래의 링크를 따라가보라. 이걸로 많이 연습해보면 좋을 것 같다.

http://media1.ajdesigner.com/p_ieee_754_word.swf


이제 이 Floating Point Number의 대단한 점을 설명해보자한다.

표로 한번 봐보자



32비트로 표현을 할 경우 너무 헷깔릴 것 같아서 짧게 8비트를 가지고 Floating Point Number를 표현해봤다. 굉장히 신기한 것은 largest denorm 값에서 자연스럽게 smallest norm으로 넘어간다는 것이다. 7/512 다음에 8/512가 나오지 않는가. 이것에 대한 2진수 표현 역시 0 0000 111에서 0 0001 000으로 자연스럽게 넘어간다. bias를 사용하지 않으면 이게 불가능해진다. (각자 해보도록 해보자.) nomalized 영역에서 largest norm 부분을 한번봐보자. 240이 표현 가능한 가장 큰 숫자이고 그 다음 큰 수가 224이다. 그렇다. 사람이 생각하는 것처럼 Floating Point Number는 모든 숫자를 차례대로 표현하지는 못 한다. 



그렇지만 이것은 8비트로 Floating Point Number를 표현했을 경우이다. 32비트로 표현하면 훨씬 큰 숫자, 훨씬 작은 숫자를 표현할 수 있기 떄문에 32비트로 Floating Point Number를 표현하면 우리가 필요료 하는 숫자들은 전부 표현가능하다고 한다.

32비트로 표현하면 얼마나 대단하게 작은 또는 큰 숫자를 표현할 수 있는지 봐보자.



어마어마한 숫자이다. 2의 127승이 분모로 들어가면 거의 0이나 다름 텐데.. 혹은 그것이 분자로 들어가면 거의 무한대나 다름 없을 텐데. 그 정도를 32비트로 표현할 수 있다는 뜻이다.


Floating Point Number에 대해서는 이 정도로 마무리 하고 다음부터는 Assembly Language를 공부해봅시다.

'System Programming' 카테고리의 다른 글

[SP] Virtual Memory (Basic Knowledge)  (1) 2013.04.23
[SP] Virtual Memory (Basic Knowledge)  (6) 2013.04.23
[SP] Floating Point Number  (0) 2013.04.15
[SP] Data Representation (2's complement)  (0) 2013.04.11
[SP] Data Representation  (0) 2013.04.09
[SP] 시작해보며...  (0) 2013.04.06
Posted by 빛나유

댓글을 달아 주세요

※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


보통 2진수를 표현하는 방법으로 컴퓨터는 2의 보수(2's Complement) 방법을 사용한다.

 

우선, 0 1 2 3 4 5 6 ... 15 를 각각 2진수로 나타내보자.(4비트로 표현하는 unsigned integer)

 

0        0000

1        0001

2        0010

3        0011

4        0100

5        0101

6        0110

7        0111

...       ...

13       1101

14       1110

15       1111

 

이와 같이 표현할 수 있다. 그런데 문제는 음수를 표현하고 싶을 때는 어떻게 하느냐가 관건이다. Sign bit을 이용하는 방법, 1의 보수를 이용하는 방법 등이 제안되었으나 결국 현재 사용하고 있는 것은 2의 보수 방법이다.

 

2의 보수를 만드는 법은 간단하다. 그저 1은 0으로 바꾸고 0은 1로 바꾼 후 마지막에 1만 더해주면 된다. 식으로는 다음과 같이 표현 가능하다. -x = ~x + 1. 4비트로 표현 가능한 2진수를 모두 나열해보자.(4비트로 표현하는 signed integer)


-8       1000

-7       1001

-6       1010

-5       1011

-4       1100

-3       1101

-2       1110

-1       1111

0         0000

1         0001

2         0010

3         0011

4         0100

5         0101

6         0110

7         0111


2의 보수의 특징을 한번 살펴보자. 32비트의 환경에서 2의 보수 범위는 아래와 같다.

Unsigned : 0 ~ 4,294,967,295(2의 32승 - 1)

Signed : -2147483648(2의 32승) ~ 2147483647(2의 32승 -1)

 

보면은 굉장히 개념이 쉽다. 바꾸는 방법도 매우 간단하고... 우리가 겨우 이거 배우려고 Chapter 2의 그 많은 내용들을 공부했을까? 아니다. 중요한 것은 2의 보수 환경에서 프로그래밍했을 때 생기는 문제점들을 집어보는 것이라고 생각한다.

 

다음 프로그램의 문제점이 무엇일까?


#include <stdio.h>


int main()

{

char i;


for(i = 0; i < 128; i++){

printf("%d ", i);

}

return 0;

}


char 형으로 i를 선언했다. 그리고 0 1 2 .... 127를 출력하려고 한다.
실제 실행 결과는 아래와 같다.

0 1 2 3 .. 127 -128 -127 ... 0 1 2 3 ... 127 -128 -127 ...

끝나지 않는다. char 형은 1바이트이다. 8비트로 표현이 되는데 127은 2진수 01111111로 표현가능하다. i가 2진수 01111111일 때 10진수127이 출력되고 그 다음은 어떻게 될까? i++을 하기 때문에 2진수 01111111 + 1 = 10000000가 된다. 그런데 signed char 형 10000000은 -128이다. 그렇다면 128이랑 비교를 하겠지? -128 < 128이다. 참이다. 그래서 -128을 출력한다. 그 이후도 계산을 해보면 -127 -126 이렇게 가게 된다. 

문제는 이러한 문제점을 컴파일러가 절대 notice해주지 않는다는 것이다. 2진수 표현 체계를 이해하지 못한 프로그래머 입장에서는 '내 컴퓨터가 고장났구나'하고 끝낼 문제인 샘이다.

이러한 문제점을 잘 이해하고 대처하기 위해서는 컴퓨터의 데이터 표현 방법을 잘 이해하고 있어야 한다. 실제로 예전에 로켓에 장착되어있는 프로그램에서 이와 같은 문제 때문에 시스템 에러가 발생하여 로켓이 추락하는 대형 참사가 일어났다고도 한다.

'System Programming' 카테고리의 다른 글

[SP] Virtual Memory (Basic Knowledge)  (1) 2013.04.23
[SP] Virtual Memory (Basic Knowledge)  (6) 2013.04.23
[SP] Floating Point Number  (0) 2013.04.15
[SP] Data Representation (2's complement)  (0) 2013.04.11
[SP] Data Representation  (0) 2013.04.09
[SP] 시작해보며...  (0) 2013.04.06
Posted by 빛나유

댓글을 달아 주세요

※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


컴퓨터에서 데이터를 다루는 방법에 대해서 생각해보자.


컴퓨터는 당연히 비트 단위로 연산을 한다. 그렇다면 흔히 말하는 비트가 무엇의 약자인가?

BIT : BInary digiT의 약자이다.

즉, 0과 1로 이루어진 데이터를 이해하는 것이 컴퓨터이다.


이러한 비트가 8개 모여있으면 8-bit(= 1 byte)라고 한다. 바이트의 학문적 정의는 The smallest addressable unit이다. 즉, 메모리에 지정할 수 있는 가장 작은 단위를 의미한다.

 

보통 현재 대부분의 컴퓨터는 32비트 CPU를 사용하고 있다. 여기에서 32비트는 무슨 의미인가? 컴퓨터 내부의 메인보드를 보면 버스라고 하는 데이터의 이동 통로가 있다. 쉽게 말해서 전선이 메인보드에 아주 작게 달라붙어있다고 생각하면 될 것 같다. 아무튼 이 버스가 32줄이 있다고 하는데... 그래서 32비트이다. 다른 말로 말하면 한번에 32개의 줄로부터 데이터가 하나 전송된다는 말이다. 가만히 생각해보자. 32비트면 4바이트다. 그러니까 32비트에서 데이터들은 32비트 혹은 그 이내로 표현 가능해야한다는 뜻이다. 아래 표를 보자.

 

 C declaration

32-bit 

64-bit 

 char

 1

 1

 short int

 2

 2

 int

 4

 4

 long int

 4

 8

 long long int

 8

 8

 char *

 4

 8

 float

 4

 4

 double

 8

 8

(단위 : 바이트)

 

보다시피 32비트 환경에서는 거의 다 4바이트로 표현 가능하지만 8비트짜리도 있다. 8바이트 짜리는 4바이트짜리 두개를 이어서 더욱 큰 숫자를 표현한 것이라고 생각하면 된다. 중요한 것은 char * 변수의 크기를 보자. 32비트에서는 4바이트, 64비트에서는 8바이트이다. 포인터값은 알다시피 주소값이다. 주소값이 32비트에서는 4바이트 64비트에서는 8바이트로 표현가능하다는 말이다. 다른 말로 말하면, 32비트에서는 2의 32승개의 주소 값을 표현할 수 있고 64비트에서는 2의 64승개의 주소 값을 표현할 수 있다는 말이 된다. (00...00 ~ 11...11 과 같이)

 

잠깐만 다른 이야기를 해보자.

 

08048394:    55                    push %ebp

08048395:    89 e5                movl %esp, %ebp

08048397:    8b 45 0c            mobl 0xc(%ebp), %eax

...

 

하나의 프로그램(*.c) 파일이 컴파일이 되면 대략 위와 같은 assembly code로 바뀌게 된다. 저 코드 중에서 가장 왼쪽에 있는 열이 무엇을 의미하는가? 저 부분이 virtual address이다. 실제로 컴퓨터의 physical한 메모리가 아니다. 아무튼 프로그램은 저 virtual address를 이용한다. 저 주소의 최소값은 00000000이고 최대값은 FFFFFFFF이다. 즉, 32비트이다. (32비트 환경에서는...)

 

다른 말로 말하면 한 프로그램이 가질 수 있는 크기는 0xFFFFFFFF개(2의 32승개) x 1byte = 4GB를 넘을 수 없다는 이야기가 나온다. (여기서 왜 1byte를 곱하는지는 위에 설명한 바이트의 정의를 생각해보면 알 수 있다.)

 

다시 본론으로 돌아와서 :-)

 

Char *이든 int *이든 어떤 형태의 포인터도 그것은 32비트에서는 4바이트 64비트에서는 8바이트이다. 왜냐하면 포인터는 주소값을 표현해주는 변수이기 때문이다.

 

이러한 32비트의 바이너리 표현을 컴퓨터는 어떻게 적을까? 여기에서 Little Endian, Big Endian 개념이 나온다.

0x01234567라는 32비트 숫자가 있다고 해보자.

Little Endian에서는 01 23 45 67 과 같이 표현되고

Big Endian에서는 67 45 23 01 과 같이 표현된다고 한다.

 

우리가 흔히 사용하는 Intel Micro Processor는 Little Endian을 사용한다. 왜 이렇게 썼을까? 이유라기 보다는 어느 정도의 추측은 할 수 있어야 한다고 한다. 왜인지는 나도 잘 모르겠다;;;;

 

다음 포스팅에서는 비트를 표현하는 방법에 대해서 이야기해보도록 하자.

'System Programming' 카테고리의 다른 글

[SP] Virtual Memory (Basic Knowledge)  (1) 2013.04.23
[SP] Virtual Memory (Basic Knowledge)  (6) 2013.04.23
[SP] Floating Point Number  (0) 2013.04.15
[SP] Data Representation (2's complement)  (0) 2013.04.11
[SP] Data Representation  (0) 2013.04.09
[SP] 시작해보며...  (0) 2013.04.06
Posted by 빛나유

댓글을 달아 주세요