정수형값을 char 형에 저장하려면?

하하의 이미지

int num = 356;

값을 2개의 charactor형에 넣어 표현하려 합니다.

단, 2개의 charactor형의 표현 범위를 넘길 경우 범위를 벗어났다고

치고 버립니다.

main ()
{
    int      num=356;
    char   buf[2];

    // 이럴경우 정수형의 값중 2byte범위에서 표현할수 있는 수를 
    // 각각의 1byte char type 에 넣습니다. 
    x[0] = ((24 << num) & 0xff000000) >> 24;
    x[1] = ((16 << num) & 0xff000000) >> 24;
   
    printf("%x   %x\n", buf[0], buf[1]);

}

위 코드를 돌려보면..

0 0 <- 이렇게 결과가 나옴니다.

음.. 제가 원하는 결과는 356은 2byte를 넘겼으니 2byte가 표현

할 수 있는 256까의 수가 각각 한 byte씩 buf[0], buf[1]에 들어

갈거라 생각 했는데.. 이상합니다.

왜 그런것일까요???

lsj0713의 이미지

#include <stdio.h>
#include <limits.h>
/* 매크로 상수 CHAR_BIT가 정의되어 있다 */

int main(void)
{
    unsigned int num=356;
    /*
        참고로 E1 >> E2 에서 E1이 signed type이고 음수값일 경우의 결과는
        implementation-defined입니다. 따라서 num의 type으로 unsigned int를 
        추천합니다.
    */ 
    unsigned char buf[2];
    /*
        표현범위보다 큰 값을 저장할 때에는 unsigned integer형이
        좋습니다. 절대로 overflow가 발생하지 않습니다. (즉, 무조건 잘립니다) 
    */

    /*
        이럴경우 정수형의 값중 2byte범위에서 표현할수 있는 수를 
        각각의 1byte char type 에 넣습니다. 
    */
    buf[0] = num >> CHAR_BIT;
    buf[1] = num;
    /*
        buf[0]이 unsigned integer이기 때문에 절대로 overflow가 
        일어나지 않습니다. 순서는 원래 코드 그대로를 따랐습니다. 즉,
        Big endian입니다.

        참고로, unsigned int의 최소범위가 0~65535 라는 것을 생각해
        볼 때 이식성을 생각해야 될 상황이라면 buf의 크기가 2보다 커지는
        것은 바람직하지 않습니다. (즉, 2바이트 까지가 표준에 보장된
        안전선이라는 뜻입니다.)
    */
    printf("buf[0] = 0x%x, buf[1] = 0x%x, num = %d\n",
        buf[0], buf[1], buf[0] * (1 << CHAR_BIT) + buf[1]);

    return 0;
}
cskblue의 이미지

하하 wrote:

int num=356;
char buf[2];
buf[0] = ((24 << num) & 0xff000000) >> 24;
------------------------------
buf[1] = ((16 << num) & 0xff000000) >> 24;
------------------------------
printf("%x %x\n", buf[0], buf[1]);
}

일단 떡 보면 0, 0나올수 밖에없네요..

숫자 24에다가 왼쪽쉬프트 num(356)만큼 하라.......;;;;
반대로 됐네요.
num << 24
고치고 나면 비슷한 답이 나올겁니다.
1 , 100 인가 100, 1인가
나머지는 기호에 맞게 고쳐쓰세요.

cdpark의 이미지

buf[0] = num & 0xFF
buf[1] = (num / 0x100) & 0xFF

왜 복잡하게 shift 연산을 총동원하죠? (그나마 틀린...)

가장 직관적인 식을 쓰고, 나머지는 컴파일러에게 맡기세요.

Risty의 이미지

아마 이렇게 하면 2바이트가 복사될 것입니다. (단 범위 검사는 따로 해야 합니다.)

*(short int *)buf = *(short int *)&num;

haze11의 이미지

union을 쓰면 어떨까요? ㅡ.ㅡa
더 쉽게 해결할 듯 한데요..^^a

하하의 이미지

Quote:

일찍일어났네?
'아직 날 모르는군;;'

이런말 여자 한테 들으셨군요.. ^^;;;;

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

최병현의 이미지

Risty wrote:
아마 이렇게 하면 2바이트가 복사될 것입니다. (단 범위 검사는 따로 해야 합니다.)

*(short int *)buf = *(short int *)&num;

Risty님께 한표!

To be a rich

하하의 이미지

Quote:

#include <stdio.h>
#include <limits.h>
/* 매크로 상수 CHAR_BIT가 정의되어 있다 */

int main(void)
{
unsigned int num=356;
/*
참고로 E1 >> E2 에서 E1이 signed type이고 음수값일 경우의 결과는
implementation-defined입니다. 따라서 num의 type으로 unsigned int를
추천합니다.
*/
unsigned char buf[2];
/*
표현범위보다 큰 값을 저장할 때에는 unsigned integer형이
좋습니다. 절대로 overflow가 발생하지 않습니다. (즉, 무조건 잘립니다)
*/

/*
이럴경우 정수형의 값중 2byte범위에서 표현할수 있는 수를
각각의 1byte char type 에 넣습니다.
*/
buf[0] = num >> CHAR_BIT;
buf[1] = num;
/*
buf[0]이 unsigned integer이기 때문에 절대로 overflow가
일어나지 않습니다. 순서는 원래 코드 그대로를 따랐습니다. 즉,
Big endian입니다.

참고로, unsigned int의 최소범위가 0~65535 라는 것을 생각해
볼 때 이식성을 생각해야 될 상황이라면 buf의 크기가 2보다 커지는
것은 바람직하지 않습니다. (즉, 2바이트 까지가 표준에 보장된
안전선이라는 뜻입니다.)
*/
printf("buf[0] = 0x%x, buf[1] = 0x%x, num = %d\n",
buf[0], buf[1], buf[0] * (1 << CHAR_BIT) + buf[1]);

return 0;
}

위의 코드를 보면서 의문이 나는 점이 있습니다.

아래와 같이 생각해 볼때....

unsigned int num = 356;

는 big endian 머신에서 실행 시 메모리에

0xA8010000(356) 으로 올라간다.

unsigned char buf[2];

buf[0] = num >> CHAR_BIT;

를 하면

num 의 모든 비트를 8bit 만큼 우측으로 이동

하라.. 따라서 0x00A80100 이 되고

buf[0]의 값에는 0x00A80100 의 가장 우측에서

8bit만이 들어가게 되어 00 이 들어간다.

마찬가지로

bit[1] = num; 은 0xA8010000 의 가장 우측에서

8bit만이 들어가게 되어 00이 들어간다.

- - ;;;;;;;;; 이건 답이 아닌데.... 제 생각이 어디서 부터

틀린건가요?????? 으으.. 머리아포...

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

하하의 이미지

main() 
{
        int num=356; 
        char buf[2]; 

        buf[0] = ((num << 24) & 0xff000000) >> 24; 

        buf[1] = ((num << 16) & 0xff000000) >> 24; 

        printf("%x %x\n", buf[0], buf[1]); 
} 

참고로 이렇게 수정하면 됩니다.

1 64 라고..

“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”

lsj0713의 이미지

하하 wrote:
위의 코드를 보면서 의문이 나는 점이 있습니다.

아래와 같이 생각해 볼때....

unsigned int num = 356;

는 big endian 머신에서 실행 시 메모리에

0xA8010000(356) 으로 올라간다.

unsigned char buf[2];

buf[0] = num >> CHAR_BIT;

를 하면

num 의 모든 비트를 8bit 만큼 우측으로 이동

하라.. 따라서 0x00A80100 이 되고

buf[0]의 값에는 0x00A80100 의 가장 우측에서

8bit만이 들어가게 되어 00 이 들어간다.

마찬가지로

bit[1] = num; 은 0xA8010000 의 가장 우측에서

8bit만이 들어가게 되어 00이 들어간다.

- - ;;;;;;;;; 이건 답이 아닌데.... 제 생각이 어디서 부터

틀린건가요?????? 으으.. 머리아포...

C의 << 와 >> 연산자는 단지 나누기, 곱하기의 의미일 뿐입니다. 빅 엔디안이건 리틀 엔디안이건 같은 결과를 보여줍니다.

E1 << E2 : E1 * 2^E2
E1 >> E2 : E1 / (2^E2)

물론 나누기와 곱하기 연산자와는 다른 몇가지 특성이 있습니다만 지금 옆에 표준문서가 없는고로 패스-_-; 일단 E1, E2 모두 양의 정수로 하는 것이 좋다는 정도로 기억해 두십시오.

참고로 union을 이용하거나 *(short int *)buf = *(short int *)&num; 와 같은 식을 사용할 경우, endian이나 수의 내부적인 표현 방법에 따라 여러가지 다른 결과가 나올 수 있습니다. 일반적으로는 쓰지 않는 편이 좋습니다.

저는 cdpark 님의 의견에 동의합니다. 직관적으로 의미가 통하는 식을 쓰고, 최적화는 컴파일러에게 맡기는 것이 바람직합니다.

ps. 첨언하자면..

    /*
        순서는 원래 코드 그대로를 따랐습니다. 즉,
        Big endian입니다.
    */

이 말인즉슨, buf[0]에는 356 중의 3이 들어가고 buf[1]에는 56이 들어간다는 뜻입니다.

ㅡ,.ㅡ;;의 이미지

하하 wrote:
int num = 356;

값을 2개의 charactor형에 넣어 표현하려 합니다.

단, 2개의 charactor형의 표현 범위를 넘길 경우 범위를 벗어났다고

치고 버립니다.

main ()
{
    int      num=356;
    char   buf[2];

    // 이럴경우 정수형의 값중 2byte범위에서 표현할수 있는 수를 
    // 각각의 1byte char type 에 넣습니다. 
    x[0] = ((24 << num) & 0xff000000) >> 24;
    x[1] = ((16 << num) & 0xff000000) >> 24;
   
    printf("%x   %x\n", buf[0], buf[1]);

}

위 코드를 돌려보면..

0 0 <- 이렇게 결과가 나옴니다.

음.. 제가 원하는 결과는 356은 2byte를 넘겼으니 2byte가 표현

할 수 있는 256까의 수가 각각 한 byte씩 buf[0], buf[1]에 들어

갈거라 생각 했는데.. 이상합니다.

왜 그런것일까요???

대단합니다... 저것이 결과가 0 0 이 나왔다고요??.. 너무 놀라워요..

전 0 0 이 안나옵니다...ㅡㅡ;;

0 0 나온다는사람 그짓말 ^^;;


----------------------------------------------------------------------------

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.