본문 바로가기
시스템프로그램

[시스템프로그램]02-1-3 정보의 표현과 활용(3)

by 케찹이 2020. 4. 26.

Type conversion 타입의 변환, 여기서 형 변환은 unsigned 과 2's complement와의 형변환을 이야기 하는 것이다. 

위 사진은 signed에서 unsigned으로 변환화는 과정이다. 보시다 싶이 2^(w-1) ~ 0은 변화가 없고 0~ -2^(w-1)일때는 x값에 2^w을 더하여 형변환이 이루어진다. signed unsigned의 형변환은 보기에는 간단하지만 막상 계산을 해보면 까다로운 부분들이 있다. 그래서 간편하게 x가 음수이면 x + 2^w, x가 양수이면 변하지 않는다라고 생각을 하면 쉽다.

unsigned에서 signed으로 변화하는 과정은 이과정의 반대이다. 그래서 딱히 더 설명을 적지 않겠다. 

 

 

그럼 실제 C언어에서의 Type conversion을 살펴 보겠다. 

일단 일반적으로 모든 상수들은 signed 형식이다. 어쩌면 당연한 것일 수도 있지만 잊지 말아야할 사항이다.

그리고 굳이 상수를 unsigned 상수로 표현을 하고 싶다면 상수뒤에 'u' 혹은 'U'를 추가하면 되겠다. Ex) 1U, 12u

 

그럼 어떠한 상황에서 sign과 unsigned에서 Type conversion이 일어날까??

전반적으로 세가지 상황이 있다. 

Explicit casting

Implicit casting

printf() 사용시 numeric value조정

 

Explicit casting은 강제형변환으로 일어나는 형변환을 말한다. 일반적으로 프로그래머가 직접 형변환을 시키는 방식이다.

밑 코드는 explicit casting의 예라고 볼 수 있다. 

int tx, ty;
unsigned ux, uy;
tx = (int) ux;
uy = (unsigned) ty;

Implicit casting은 자동 형변환이라고 생각하면 되겠다. 쉬운 예제로 이해해보도록 하자.

int f(unsigned);
tx = ux;
f(ty);

ux를 그냥 tx에서 가져가버리면 ux는 unsigned인데 signed int인 tx에 가져다버리면 ux는 어쩔수없이 자동적으로 signed이 되겠죠. 그리고 procedure call에서도 implicit casting이 발생합니다. f라는 함수에 ty를 parameter로 주었을때 f의 paremeter는 unsigned이 와야 되는데 ty라는 signed값이 들어왔을 때 자동형변환이 발생합니다. 

 

그리고 마지막으로 printf()상황은 printf괄호안에 %u를 사용할 때 발생하는 형변환입니다. 

 

C언어에선 signed인수와 unsigned인 수가 operate하였을 때 그 결과값은 unsigned으로 casting됩니다. 

그럼 다음의 몇가지 예제로 어떤식으로 값이 영향을 받는지 볼까요?

 

0 ==0U  타입이 unsigned일때 왼쪽의 0은 signed이겠죠 그리고 우측 0은 뒤에 U가 붙었으므로 unsigned타입입니다. 그럼 결국 signed인 값을 unsigned으로 변형을 해줘야겠네요. signed 0을 unsigned으로 변형하면 0입니다. 변화가 없죠. 그러므로 값은 1입니다. 

 

-1<0U 타입이 unsigned일때, 위와 같은 이유로 signed값을 unsigned으로 바꿔야겠죠. 그런데 signed 1은 이진수로 00000..000이니까 UMax = 2^w-1이 나오겠죠. 그러므로 틀린 식이므로 값은 0입니다. 

 

 

 

그 다음엔 변수가 확장되었을 때 어떤식으로 확장되는지 살펴보도록 하겠습니다. 

변수의 확장 방법은 두가지 방법이 있습니다. 첫번째는 Zero Extension 두번째는 Signed Extension입니다. 그럼 하나씩 살펴보도록 하겠습니다. 

 

Zero extension은 unsigned 변수들이 확장될때 사용됩니다. zero extension은 그냥 추가되는 비트들을 0으로 채우는 식의 extension입니다.

          1 0 1 1 1

위와 같은 5비트의 숫자를 5비트를 더 추가한 10비트 숫자로 형변환을 진행한다면

0 0 0 0 0 1 0 1 1 1

위 처럼 추가된 비트는 모두 0으로 채워지게 된다. 

 

unsigned에 대한 zero extension은 간단하지만 signed변수들은 맨 왼쪽 비트(MSB)는 sign bit이기 때문에 이를 지켜주기 위하여 Sign extension을 사용한다. arithmetic shift와 같은 식으로 비트가 생성된다고 생각하면 된다. 

        0 1 0 1

위 와같이 5를 의미하는 4비트 signed가 있고 8비트변수로 변환하고 싶다면 밑과 같이 변환된다.

0 0 0 0 0 1 0 1

위의 예시는 unsigned와 같으니 부가적인 설명을 하지 않고 음수일 경우의 예제를 하나 더 살펴보자.

 

        1 0 1 1

위는 -5값이란 4비트 변수의 이진수 표현이고 음수이기 때문에 MSB값 1을 extension한다.

1 1 1 1 1 0 1 1

8비트 변수로 변환 하였고 직접 계산을해서 검산을 해보면 1+2+8+16+32+64+(-128) = -5 똑같이 -5가 나온다. 

 

변수가 증가하는 경우를 살펴봤으니 변수가 줄어드는 경우도 살펴보자 이렇게 변수가 줄어드는 것을 Truncating이라고 한다. 근데 Truncating하는 방식은 매우 간단하다 . 다만 결과는 그렇지 않다는게 문제다. 비트가 줄어들지만 그에 대한 대처로는 아무것도 할 수 없다. 비트값이 없어지니 결과값은 당연히 이상한 값이 출력된다. 

 

 

댓글