[완료] char[4]에 담긴 값을 int로 변환할 때...
글쓴이: linuxgeek / 작성시간: 토, 2009/07/11 - 6:39오전
little endian으로 표기된 특정 4바이트를 읽어 와서 int값으로 변환하는 방법을 좀 알려 주십시요.
예를 들어.
0x01 0x00 0x00 0xFF 라는 값을 각각 char[0] char[1] char[2] char[3]에 담았다고 할 때.
little endian이니까 0xFF 0x00 0x00 0x01로 revert 시킨 다음 int i = (int) test; 하면 되지 않을까라는 생각을 해 봤는데 역시 말도 안되는 방법이었던 거 같네요.
아무래도 int i = 0; 에다 char를 하나씩 쉬프트해 넣는거 같은데 워낙 비트 연산에 약해서 잘 모르겠습니다.
쉽게 설명 좀 부탁 드리겠습니다.
Forums:
어렵지 않습니다
메모리상에 0x01, 0x02, 0x03, 0x04 순서로 있다면
char mem[] = { 0x01, 0x02, 0x03, 0x04 };
이걸 그냥 int *로 간주하고 값을 얻으면 됩니다.
int val = * (int *)mem;
이러면 val==0x04030201 이 됩니다.
반면 big endian 시스템이라면 val==0x01020304 가 되고요.
순서를 바꿀 필요가 있는 건 메모리 상의 저장 값과 시스템이 서로 다른 endian을 가지고 있을 때 뿐입니다.
다만 이 방법은 문제 소지가 있습니다. memory align이 맞지 않으면 죽는 시스템이 있습니다.
예를 들어 mem의 주소가 0x10000이면 괜찮은데, 0x10001이면 죽을 수 있다는 거죠..
(x86을 쓰는 PC는 괜찮지만, 모바일 기기에 많이 쓰이는 ARM은 문제가 발생합니다)
이경우 비트 연산이 필요한데 너무 어렵게 생각하지 않으셔도 됩니다.
val = 0x04030201 = 0x04000000 | 0x030000 | 0x0200 | 0x01 = (mem[3]<<24) | (mem[2]<<16) | (mem[1]<<8) | mem[0];
입니다. 만약에 메모리 값을 big endian으로 해석하고 싶다면
val = 0x01020304 = (mem[0]<<24) | (mem[1]<<16) | (mem[2]<<8) | mem[3];
이 되겠죠. *(int *)가 시스템의 endian에 따라 결과가 달라진다면 bit shift를 쓰는 방식은 endian의 영향을 받지 않는 장점이 있죠.
자세한 답변 감사
자세한 답변 감사 드립니다. 많은 도움이 되었습니다.
===================================================================
8-bit
===================================================================
8-bit
union을 활용
union을 활용해 보세요.
#include
union Test {
int x;
char y[4];
};
int main() {
int i;
union Test t1;
t1.x = 10;
printf("%d\n", t1.x);
for( i = 0; i<4; i++) {
printf("%02x\n", t1.y[i]&0x0ff );
}
return 0;
}
순간을 지배하는 사람이 인생을 지배한다.
한 번도 써 본적이
한 번도 써 본적이 없지만 union을 사용하면 되는군요.
아이디어 감사 드립니다.
===================================================================
8-bit
===================================================================
8-bit
int val = * (int
int val = * (int *)mem;
이것은 좋은 방법이 아닙니다.
정렬 문제 때문에 시스템에 따라 bus error 등이 유발될 수도 있기 때문입니다.
비트 연산을 쓰시는 것이 정석입니다.
Orion Project : http://orionids.org
테스트를 해 봤는데
테스트를 해 봤는데 제가 뭘 잘못 한건지 생각하던 결과가 아닌데요. 뭐가 잘못 되었을까요?
결과:
===================================================================
8-bit
===================================================================
8-bit
char 형이라
어라 신기하게도 shift한 다음에 보니 상위 비트가 1로 채워지네요. 아래처럼 해보세요.
i = (a[0] << 24)&0xFF000000 | (a[1] << 16)&0xFF0000 | (a[2] << 8)&FF00 | (a[3])&0xFF
--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...
http://mytears.org ~(~_~)~
나 한줄기 바람처럼..
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...
http://mytears.org ~(~_~)~
나 한줄기 바람처럼..
아 그렇군요. 그럼
아 그렇군요. 그럼 unsigned char로 하면 되겠네요.
답변 감사 드립니다.
===================================================================
8-bit
===================================================================
8-bit
비트 연산이
비트 연산이 싫으시면 256씩 곱해 나가면서 더하면 됩니다.
256진법이라 생각하면 쉽죠.
물론 char, int 둘다 unsigned 형이어야 합니다.
그리고 unsigned int형 보다는 stdint.h에 정의된 uint32_t 형을 춫헌...
uint32_t i = ( ( ( (uint32_t)a[0] * 256) + a[1]) * 256 + a[2]) * 256 + a[3];
만약 사용하시는 플랫폼에서 제공하는 리틀/빅 엔디안 변환 함수가 있다면
웬만하면 그걸 사용하시는 쪽을 강추합니다.
댓글 달기