인프라

[가마] 센서 데이터를 java 로 받을때 문제점 빅엔디안/리틀엔디안

소행성왕자 2023. 7. 14. 14:46

Bit

컴퓨터가 데이터를 처리하기 위해 사용하는 데이터의 최소 단위입니다.

이러한 비트에는 2진수의 값(0과 1)을 단 하나만 저장할 수 있습니다.

Byte

위와 같은 비트가 8개 모여서 구성되며, 한 문자를 표현할 수 있는 최소 단위입니다.

바이트 저장 순서(byte order)

컴퓨터는 데이터를 메모리에 저장할 때 바이트(byte) 단위로 나눠서 저장합니다.

하지만 컴퓨터가 저장하는 데이터는 대게 32비트(4바이트)나 64비트(8바이트)로 구성됩니다.

따라서 이렇게 연속되는 바이트를 순서대로 저장해야 하는데, 이것을 바이트 저장 순서(byte order)라고 합니다.

이때 바이트가 저장되는 순서에 따라 다음과 같이 두 가지 방식으로 나눌 수 있습니다.

  • 빅 엔디안(big endian)
  • 리틀 엔디안(little endian)

빅 엔디안(big endian)

빅 엔디안 방식은 낮은 주소에 데이터의 높은 바이트(MSB, Most Significant Bit)부터 저장하는 방식입니다.

이 방식은 평소 우리가 숫자를 사용하는 선형 방식과 같은 방식입니다.

따라서 메모리에 저장된 순서 그대로 읽을 수 있으며, 이해하기가 쉽다는 장점을 가지고 있습니다.

SPARC을 포함한 대부분의 RISC CPU 계열에서는 이 방식으로 데이터를 저장합니다.

예를 들어 다음과 같이 저장할 32비트 크기의 정수가 있다고 가정합니다.

예제

0x12345678

이 정수는 각각 다음과 같이 1바이트값 4개로 구성됩니다.

예제

0x12, 0x34, 0x56, 0x78


리틀 엔디안(little endian)

리틀 엔디안 방식은 낮은 주소에 데이터의 낮은 바이트(LSB, Least Significant Bit)부터 저장하는 방식입니다.

이 방식은 평소 우리가 숫자를 사용하는 선형 방식과는 반대로 거꾸로 읽어야 합니다.

대부분의 인텔 CPU 계열에서는 이 방식으로 데이터를 저장합니다.

앞서 예를 든 정수 "0x12345678"를 리틀 엔디안 방식으로 저장하면 다음 그림과 같이 저장됩니다.

Double 형식

-64   8 0 0 0 0    => -3
-64   0 0 0 0 0    => -2
-65 -16 0 0 0 0    => -1
  0   0 0 0 0 0    => 0
63  -16 0 0 0 0    =>  1
64    0 0 0 0 0    =>  2
64    8 0 0 0 0    =>  3
64   16 0 0 0 0    =>  4

public class Main {

    public static void main(String[] args) {
        byte[] data = new byte[]{64, 8, 0, 0, 0, 0, 0, 0};
        double value = Double.longBitsToDouble(ByteBuffer.wrap(data).getLong());
        System.out.println(value);
    }
}

이 코드는 data라는 이름의 byte[] 배열을 생성합니다. 이 배열에는 "64 8 0 0 0 0 0 0" 문자열을 나타내는 바이트가 들어 있습니다. value라는 이름의 double 변수를 선언하고 ByteBuffer 클래스의 getLong() 메서드를 사용하여 data 배열의 내용을 long 값으로 변환합니다. 그런 다음 Double 클래스의 longBitsToDouble() 메서드를 사용하여 long 값을 double 값으로 변환합니다. 마지막으로 System.out.println() 메서드를 사용하여 value 변수의 값을 출력합니다.

이 코드를 실행하면 다음과 같은 출력이 표시됩니다.

3.0

int32 형식

public class Main {

    public static void main(String[] args) {
        byte[] bytes = {0, 0, 0, 1};
            int value = ByteBuffer.wrap(bytes).getInt();
            System.out.println(value); // 1
    }
}

int64 형식

public class Main {

    public static void main(String[] args) {
        byte[] bytes = {8, -37, -124, -121, -113, 88, -7, 10};
            long value = ByteBuffer.wrap(bytes).getlong();
            System.out.println(value); // 1
    }
}