Language/C

Type casting 시 주의해야할 점. (signed, unsigned)

TechNote.kr 2016. 7. 4. 16:25
728x90

 socket을 통해 받아들이는 1 byte (8 bit) 정보를 처리해야 할 일이 생겼다. 해당 값은 0xEE(10진수: 238) 이었다. 0xEE는 0xFF(256)보다 작은 값으로 8 bit만으로 처리가 가능한 값이다. 이에 아래와 같이 송수신하도록 코드를 작성하였다. 



unsigned int len;

char sendbuf[4];


len = 238;

sendbuf[0] = len;


이후 sendbuf 송신.........

unsigned int len;

char receivebuf[4];


receivebuf에 수신...........


len = *(receivebuf+1);


송신측에서 전송한 238(0xEE)를 그대로 수신하여 변수에 저장할 것이라고 예상하였지만 결과는 -18로 저장되고 말았다. unsigned int 형임에도 불구하고 음수로 저장하고 있었다. 


len = (unsigned int)(*(receivebuf+1)) 


혹시나 해서 unsigned int로 강제로 다시한번 casting 한 후 다시 확인해 보았지만 결과는 동일하였다. 다소 이해가 가지 않는 결과에 여러가지 테스트를 진행해 보았다. 



char a=0xEE;


[출력결과]

char a : -18

HEX : EE

signed char 형으로 238(0xEE)을 저장할 경우 -18로 표기가 된다. signed char 형은 (-128 ~ 127) 사이기때문에 -18 로 표기되는 것이 정상적이다. 


char a=0xEE;

int b = a;


[출력결과]

int b : -18 (size : 4)

signed char -> signed int

HEX : FF FF FF EE

1 byte의 signed char을 4 byte의 signed int로 변환할 경우 결과에서 보듯이 이미 음수로 표시된 값이 int 형으로 단순히 확장만 이루어짐을 알수 있다. 


char a=0xEE;

unsigned int c = a;


[출력결과]

unsigned int c : -18 (size : 4)

signed char -> unsigned int

HEX : FF FF FF EE

1 byte의 signed char을 4 byte의 unsigned int로 변환하는 경우가 이 test code를 만들게 된 케이스였다. 결과에서 보듯이 signed int로 casting 하는 경우와 별반 다르지 않게 FF FF FF EE (-18)로 결과가 출력되었다. 


char a=0xEE;

unsigned char d = a;


[출력결과]
unsigned char d : 238 (size : 1)
signed char -> unsigned char
HEX : EE

 같은 char 형의 unsigned 로 변환해 보았다. 1 byte의 signed char를 1 byte의 unsigned char로 변환하니 정상적으로 casting 되었다. HEX값은 EE로 동일하지만 printf 로 출력시 -18에서 238로 변경되었다. 


char a=0xEE;

unsigned int e = (unsigned char)a;


[출력결과]
unsigned int e : 238 (size : 4)
signed char -> unsigned char -> unsigned int
HEX : 00 00 00 EE

 signed char에서 unsigned int로 변환시 의도와 같이 -18에서 238으로 표시가 되도록 하려면 어떻게 해야할 지 고민해 보았는데 위와 같이 하면 된다. 


우선 같은 type의 unsigned 로 변환한 후 다른 type으로 확장하는 것이다. 

즉, signed char 에서 unsigned char로 1차 casting을 진행하고, unsigned char 에서 unsigned int로 2차 casting을 하면 원하는 값으로 변환할 수 있다. 


변경을 원하는 type보다 더 큰 size의 type으로 casting시에 unsigned, signed 까지 casting 을 고려한다면 위의 내용을 명심해 둘 필요가 있다. 



728x90

'Language > C' 카테고리의 다른 글

Signed / Unsigned 의 비교  (0) 2019.08.24
sizeof - 함수가 아닌 연산자.  (0) 2016.07.04
memset - 하위1byte pattern 의 이해  (2) 2016.07.01