카테고리 없음

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

멜번초이 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 이다.