[질문] 리틀엔디안 빅엔디안.

bizzare의 이미지

SunOS에서 세이브한 파일을
윈도우에서 읽으려고 하니까 안되더군요.

그 원인을 찾아 헤매다가 '리틀엔디안, 빅엔디안'때문에 생기는 문제라는 것을 알았습니다.

int i = 10;
fread( (void*)&i, sizeof( short ), 1, m_pFile);

를 하면

윈도우에서는 int 10 이
0x0000000a 인데

SunOS에서는 이것이
0x0a000000 이더군요.

이런 문제를 해결하려면 일일이 분기를 해줘야 하나요?
이런걸 쉽게 처리해주는 라이브러리같은 것은 없는지요.

지금 세이브용 클래스를 만들어놓고 쓰고 있었는데 이 부분을 전혀 고려하지 않고 있었거든요.

조언 부탁드립니다.

heoks의 이미지

리틀이냐 빅이냐는 정수 값에만 해당되는 것 같습니다.
저 같은 경우는 파일에 값을 쓸때 문자열로 정수값을 써버립니다. :oops:

fprintf(fp, "%d", value);

아니면 해당 정수값이 경우는 ntohl 함수를 사용하면 되지 않을까 싶네요.

lifthrasiir의 이미지

bizzare wrote:
SunOS에서 세이브한 파일을
윈도우에서 읽으려고 하니까 안되더군요.

그 원인을 찾아 헤매다가 '리틀엔디안, 빅엔디안'때문에 생기는 문제라는 것을 알았습니다.

int i = 10;
fread( (void*)&i, sizeof( short ), 1, m_pFile);

를 하면

윈도우에서는 int 10 이
0x0000000a 인데

SunOS에서는 이것이
0x0a000000 이더군요.

이런 문제를 해결하려면 일일이 분기를 해줘야 하나요?
이런걸 쉽게 처리해주는 라이브러리같은 것은 없는지요.

지금 세이브용 클래스를 만들어놓고 쓰고 있었는데 이 부분을 전혀 고려하지 않고 있었거든요.

조언 부탁드립니다.

간단하게 다음과 같이 만들어 써도 됩니다. 많은 컴파일러 및 라이브러리들이 이런 경우를 위해서 최적화된 함수를 제공하기도 하고요.

#if LITTLE_ENDIAN
#    define Swap32LE(x) (x)
#    define Swap32BE(x) ((((x) & 0xff000000) >> 24) | (((x) & 0xff0000) >> 8) | (((x) & 0xff00) << 8) | (((x) & 0xff) << 24))
#else
#    define Swap32LE(x) ((((x) & 0xff000000) >> 24) | (((x) & 0xff0000) >> 8) | (((x) & 0xff00) << 8) | (((x) & 0xff) << 24))
#    define Swap32BE(x) (x)
#endif

이렇게 만들고 little endian으로 된 데이터를 읽을 때는 Swap32LE(x)를 호출하고... 하면 됩니다. htonl이나 ntohl 같은 것들도 이런 역할을 하고요.

- 토끼군

BuzzLy의 이미지

heoks wrote:
리틀이냐 빅이냐는 정수 값에만 해당되는 것 같습니다.
저 같은 경우는 파일에 값을 쓸때 문자열로 정수값을 써버립니다. :oops:

fprintf(fp, "%d", value);

아니면 해당 정수값이 경우는 ntohl 함수를 사용하면 되지 않을까 싶네요.

float나 double같은 type에도 이런 문제가 있지 않나요?

superwtk의 이미지

1바이트를 초과하는 모든 타입에 문제가 있을것 같은데요..

wchar 같은 타입도 그럴것 같고.. (unsigned short ??)

euc-kr이나 UTF-8로 인코딩 되어있고 한글을 포함하고 있는 파일은 어찌 될지 궁금하군요=_=

heoks의 이미지

BuzzLy wrote:
heoks wrote:
리틀이냐 빅이냐는 정수 값에만 해당되는 것 같습니다.
저 같은 경우는 파일에 값을 쓸때 문자열로 정수값을 써버립니다. :oops:

fprintf(fp, "%d", value);

아니면 해당 정수값이 경우는 ntohl 함수를 사용하면 되지 않을까 싶네요.

float나 double같은 type에도 이런 문제가 있지 않나요?

밑에 superwtk 님이 얘기하신 것처럼 2byte 이상인 것은 모두이겠지요.

실수형에 포멧은 정수형과는 틀린 것으로 알고 있습니다. 자세한 건 고수님들이 의견을 주시면 좋겠네요. :roll:

메모리를 굉장히, 엄청나게, 절대적으로 아껴야 하는 상황이 아니라면 char [] 사용하는 것이 좋다고 생각합니다. 그리고 원래 파일이 char [] 잖아요? 아닌가? ㅎㅎ

lifthrasiir의 이미지

heoks wrote:
BuzzLy wrote:
heoks wrote:
리틀이냐 빅이냐는 정수 값에만 해당되는 것 같습니다.
저 같은 경우는 파일에 값을 쓸때 문자열로 정수값을 써버립니다. :oops:

fprintf(fp, "%d", value);

아니면 해당 정수값이 경우는 ntohl 함수를 사용하면 되지 않을까 싶네요.

float나 double같은 type에도 이런 문제가 있지 않나요?

밑에 superwtk 님이 얘기하신 것처럼 2byte 이상인 것은 모두이겠지요.

실수형에 포멧은 정수형과는 틀린 것으로 알고 있습니다. 자세한 건 고수님들이 의견을 주시면 좋겠네요. :roll:

메모리를 굉장히, 엄청나게, 절대적으로 아껴야 하는 상황이 아니라면 char [] 사용하는 것이 좋다고 생각합니다. 그리고 원래 파일이 char [] 잖아요? 아닌가? ㅎㅎ

실수형(정확히는 IEEE-754 부동 소숫점 표현)도 정수형처럼 endian의 영향을 받습니다. 따라서 실수형으로 표현한 숫자 하나와 같은 크기의 정수형(예를 들어서 double이라면 64비트 정수형)으로 표현한 숫자 하나는 1:1으로 대응됩니다. 단지 각 비트를 어떻게 해석하느냐만 다를 뿐이고요.

superwtk wrote:
euc-kr이나 UTF-8로 인코딩 되어있고 한글을 포함하고 있는 파일은 어찌 될지 궁금하군요=_=

그런 경우에는 항상 char로 표현되고 multibyte sequence의 바이트 순서가 정해져 있으므로 문제가 없습니다.

- 토끼군

BuzzLy의 이미지

tokigun wrote:

간단하게 다음과 같이 만들어 써도 됩니다. 많은 컴파일러 및 라이브러리들이 이런 경우를 위해서 최적화된 함수를 제공하기도 하고요.
#if LITTLE_ENDIAN
#    define Swap32LE(x) (x)
#    define Swap32BE(x) ((((x) & 0xff000000) >> 24) | (((x) & 0xff0000) >> 8) | (((x) & 0xff00) << 8) | (((x) & 0xff) << 24))
#else
#    define Swap32LE(x) ((((x) & 0xff000000) >> 24) | (((x) & 0xff0000) >> 8) | (((x) & 0xff00) << 8) | (((x) & 0xff) << 24))
#    define Swap32BE(x) (x)
#endif

이렇게 만들고 little endian으로 된 데이터를 읽을 때는 Swap32LE(x)를 호출하고... 하면 됩니다. htonl이나 ntohl 같은 것들도 이런 역할을 하고요.

- 토끼군

float나 double인 경우는 bitwise 연산이 안되는데 어떻게 하는 것이
좋은지요? IBM690 cluster 에서(big endian) 만든 binary화일을
pc(little endian) 에서 읽으려는데 C를 이용하려구요.
이것때문에 시간 참 많이 소비하게 되네요... 첨부터 HDF5 같은 걸 이용하면
좋은데...

익명 사용자의 이미지

Quote:

float나 double인 경우는 bitwise 연산이 안되는데 어떻게 하는 것이
좋은지요? IBM690 cluster 에서(big endian) 만든 binary화일을
pc(little endian) 에서 읽으려는데 C를 이용하려구요.
이것때문에 시간 참 많이 소비하게 되네요... 첨부터 HDF5 같은 걸 이용하면
좋은데...

별수없이 해당환경에 특화된 공용체&비트필드를 이용하거나 혹은 포인터를 이용한 편법을 동원해야 되겠지요.

swunk의 이미지

유사한 내용이라서 이어서 질문 합니다.

같은 소스코드를 가지고 리틀인디안 시스템에서도 사용하고 빅인디안 시스템에서도 사용코자 합니다.

즉,

#ifdef BIG_ENDIAN
int a=100;
int b=200;
end if

#ifdef LITTLE_ENDIAN
int c=300;
int d=400;
#endif

이런식으로 정의해 놓고 시스템에 따라 콤파일만 다시하면 모두 사용가능케 하고 싶은데 잘 안되네요...

어떻게 하면 될까요 ?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.