카테고리 없음

[빅엔디안/리틀엔디안] 체크 방법과 바이트오더변환 함수

멜번초이 2023. 10. 15. 19:04

컴퓨터가 숫자를 메모리에 저장하는 방식에 두가지가 있다.

두가지 각각 장단점이 있어서 뭐가 낫다고 말할 수는 없으나 내가 프로그램 짜고 있는 시스템에서는 어떤 방식으로 숫자를 저장하는지 알아두는 것은 나쁠 것은 없다.

​

빅 엔디안(Big endian) 방식 ​

​

빅 엔디안은 중요성이 높은 바이트부터 저장하는 방식이다. 우리가 평소에 숫자를 사용하는 방식과 같고 저장된 순서 그대로 읽을 수 있어서 이해하기 쉽다.

예를 들어 0x12345678 이라는 데이터가 있다. 여기서 0x12는 0x78 보다 휠씬 큰 단위이고 중요성이 높다고 볼 수 있다.

0x는 16진수라는 의미이고 16진수 2자리가 한 byte를 표현되므로 이 정수는 아래와 같이 4 byte로 표시된다.

0x12, 0x34, 0x56, 0x78

​

리틀 엔디안(Littlen endian) 방식 ​

​

리틀엔디안 방식에서는 빅엔디안과 반대 순서로 메모리에 저장된다.

따라서 0x12345678을 저장하면 메모리에 다음과 같은 순서로 저장된다.

0x78, 0x56, 0x34, 0x12

​

엔디안 체크 endianness check

#include <stdio.h>

int main () {

    unsigned int x = 0x12345678;

    char *c = (char*) &x;

    printf ("value : %x %x %x %x\n", *c, *(c+1), *(c+2), *(c+3));

    if (*c == 0x12) {

        printf ("Big endian. \n"); }

    else {

        printf ("Little endian. \n");

    }

    return 0;

}

위의 프로그램을 Big 엔디안시스템에서 수행했을 때 결과는

​

value : 12 34 56 78

Big endian​

​

만약에 little 엔디안 시스템에서 프로그램을 수행했을 때 결과는

​

value : 78 56 34 12

Little endian ​

 

그리고,

Big엔디안이면 0, little 엔디안이면 1 을 리턴하는 함수를 구현해보면 다음과 같다.

int is_little_endian()

{

    unsigned int x = 1;

    char *c = (char*) &x;

    return (int)*c;

}

1은 Big endian 에서는 00 01 이 될것이고 첫바이트 리턴하면 0 이 리턴 될 것이다. Little endian 에서는 01 00으로 저장될 것이고 첫바이트 리턴하면 1이 리턴 되는 원리이다.​

​

Byte Order 변환

​

그렇다면 little 엔디안 시스템에서 여타의 이유로 메모리의 값을 Big 엔디안의 Byte order 로 변환해야 하는 경우가 있다면 htons, htonl 함수를 사용한다. 반대 경우의 함수로는 ntohl, ntohs 가 있으며 여기서 h는 host byte order, n 은 network byte order 를 의미하며 Big 엔디안을 의미한다. 함수에 대한 자세한 사용법은 인터넷 찾아보면 되니 생략한다.

위 함수들은 유닉스/리눅스에서 시스템함수로 제공되고 있다.

​

[방과 후 학습]

0x12345678 에서 0x12가 0x78보다 가중치가 높다는 것을 이해 못 하신 분들을 위해서..

0x12345678 은 십진수로 얼마일까?

=0x12×256³+0x34×256²+0x56×256¹+0x78

=18×256³+52×256²+86×256¹+120

=305419896

1byte 는 2⁸ 즉 256 이다.