char, unsigned char 에 대해서.

moonzoo의 이미지

#include <stdio.h>

int main()
{
    char c1 = 0xcd;
    unsigned char c2 = 0xcd;

    if( c1 == c2)
        printf("Equal\n");
    else
        printf("c1=[%x], c2=[%x]\n",c1,c2);

}

위의 결과는 다음과 같습니다.

c1=[ffffffcd], c2=[cd]

궁금한 점은 c1, c2모두 1byte인데도 불구하고

c2는 cd로 출력되는데,

c1은 ffffffcd 와 같이 앞에 ffffff가 붙는 이유가 궁금합니다.

winner의 이미지

char 는 signed char 와 unsigned char 중 하나를 선택할 수 있습니다.
만약 signed char 이면 char 가 표현할 수 있는 것은 -128~127 까지죠.

위의 수는 16진수로 127을 넘습니다.
%x 는 무부호 16진 출력입니다.

계산은 안 해봤습니다만 16진수가 미묘해서 뒤쪽의 수가 변하지 않은 것 같습니다.

winner의 이미지

제대로 읽어보지는 않았습니다만 이런 내용들이 담긴 것으로 아는데.

cdpark의 이미지

overflow가 아니고 sign extension이죠.

bh의 이미지

moonzoo wrote:
#include <stdio.h>

int main()
{
    char c1 = 0xcd;
    unsigned char c2 = 0xcd;

    if( c1 == c2)
        printf("Equal\n");
    else
        printf("c1=[%x], c2=[%x]\n",c1,c2);

}

위의 결과는 다음과 같습니다.

c1=[ffffffcd], c2=[cd]

궁금한 점은 c1, c2모두 1byte인데도 불구하고

c2는 cd로 출력되는데,

c1은 ffffffcd 와 같이 앞에 ffffff가 붙는 이유가 궁금합니다.

저두 테스트를 해봤습니다.
16진수 코드가 좀 어색해서..
이걸 10진수로 변경해 봤습니다.

c1 = 205 일때
c1 = -205 일때
결과값은 각각
c1=[-51], c2=[205] // 오버플로우
c1=[51], c2=[205] // 언더플로우

여기서 얻은 공식.. (FreeBSD/i386 gcc 에서 테스트 했습니다)
(오버플로우 결과값) = -{(자료형의 최대범위 값) - (입력값)}
(언더플로우 결과값) = {(자료형의 최대범위 값) - (입력값)}

단지 수학에서
c1=[ffffffcd] 를 어떻게 표현하느냐만 이해하면 될거 같아요.

--
이 아이디는 이제 쓰이지 않습니다.

bh의 이미지

cdpark wrote:
overflow가 아니고 sign extension이죠.

두가지 개념은 어떤 차이가 있는지요..?
고견을 듣고 싶습니다.

꾸벅..

황병희 드림

--
이 아이디는 이제 쓰이지 않습니다.

버려진의 이미지

음.. 일단 비교문에 문제가 있습니다. 오버플로우는 오버플로우인데요..

phrack지에 integer overflow라는 제목으로 기사가 실렸습니다.

대략 signed형 변수와 unsigned형 변수를 비교할때의 처리 방식 때문입니다.

http://www.phrack.org/phrack/60/p60-0x0a.txt

예전에 번역한게 있는데.. 지금보니 너무 이상해서 차마 보여드리지 못하겠습니다 :cry:

출력값은 위에 답변이 있으니 생략하겠습니다.

pynoos의 이미지

bh wrote:

c1=[-51], c2=[205] // 오버플로우
c1=[51], c2=[205] // 언더플로우

여기서 얻은 공식.. (FreeBSD/i386 gcc 에서 테스트 했습니다)
(오버플로우 결과값) = -{(자료형의 최대범위 값) - (입력값)}
(언더플로우 결과값) = {(자료형의 최대범위 값) - (입력값)}

언더플로우라는 말은 실수형에서 0에 가까운 소수를 표현못할 때 사용되는 말이고, 음의 범위를 벗어날 때는 오버플로라는 말을 그대로 사용합니다. 제가알기론.. 8)

bh의 이미지

pyj200 wrote:
음.. 일단 비교문에 문제가 있습니다. 오버플로우는 오버플로우인데요.. phrack지에...........
http://www.phrack.org/phrack/60/p60-0x0a.txt

링크 감사드립니다.. 꾸벅,,

--
이 아이디는 이제 쓰이지 않습니다.

bh의 이미지

pynoos wrote:
bh wrote:

c1=[-51], c2=[205] // 오버플로우
c1=[51], c2=[205] // 언더플로우

여기서 얻은 공식.. (FreeBSD/i386 gcc 에서 테스트 했습니다)
(오버플로우 결과값) = -{(자료형의 최대범위 값) - (입력값)}
(언더플로우 결과값) = {(자료형의 최대범위 값) - (입력값)}

언더플로우라는 말은 실수형에서 0에 가까운 소수를 표현못할 때 사용되는 말이고, 음의 범위를 벗어날 때는 오버플로라는 말을 그대로 사용합니다. 제가알기론..


지적해주셔서.. 정말 감사드립니다..
헌데 아직 위에 pynoos님이 정의해주신 뜻이 제 짧은머리론 도저히 이해가 안 옵니다..
언더플로우와 오버플로우에 해당하는 예제코드를 좀 보여주시면 안될까요..?
부탁드리겠습니다.. 꾸벅,,

--
이 아이디는 이제 쓰이지 않습니다.

moonzoo의 이미지

오버플로우는 아니라고 생각합니다.

char , unsigned char 는 1byte 이기 때문에

0xcd 1byte문자를 넣는것이 오버플로우를 발생 시킬리는

없다고 생각합니다. (오버플로우로 생각하시는 분은 아마도

0xcd 를 205로 해석하셔서 그런것 같습니다. )

다만 궁급했던 점은 %x로 찍었을때 ffffffcd 와 같이

앞의 ffffff 의 3byte가 출력됬는데..이게 실제로 메모리에

반영되는가? 하는 문제였는데.

그렇지 않더군요..

printf에서 %x로 16진수를 표현할때 음수의 경우

signed cha와는 signed int

의 표현방식이 동일하게 취급되는것 같군요.

jinushun의 이미지

Quote:
printf에서 %x로 16진수를 표현할때 음수의 경우

signed cha와는 signed int

의 표현방식이 동일하게 취급되는것 같군요.

저도 이렇게 생각이 됩니다.

하지만 오버플로우가 안일어났다는 건 좀 이해가 안되네요 :(

제생각엔 오버플로는 일어났다고 생각하는데요..

아닌건가..

가르침을 주십시오

----------------------------
www.nate.com
----------------------------

girneter의 이미지

bh wrote:
pynoos wrote:

언더플로우라는 말은 실수형에서 0에 가까운 소수를 표현못할 때 사용되는 말이고, 음의 범위를 벗어날 때는 오버플로라는 말을 그대로 사용합니다. 제가알기론..

지적해주셔서.. 정말 감사드립니다..
헌데 아직 위에 pynoos님이 정의해주신 뜻이 제 짧은머리론 도저히 이해가 안 옵니다..
언더플로우와 오버플로우에 해당하는 예제코드를 좀 보여주시면 안될까요..?
부탁드리겠습니다.. 꾸벅,,

예제 코드는 underflow 를 일으키는 값이 얼만지 몰라서
제시를 못하구요.

학교 다닐때 배운 기억을 얼핏 되살려 보면
어떤 자료형이든 모든 실수를 표현할수는 없다는건
분명합니다.
그게 그 '수'가 자료형보다 커서 그 자료형으로 제대로 처리할수
없을 때 overflow 라고 하구요.
그 '수'의 절대값이 너무너무 작아서 표현할수 없는 경우에
underflow 라고 합니다.
예를 들어 어떤 자료형이 0.00001 보다 작은 수는 표현할수 없다고하면
어떤 계산의 결과로
0.0000000001 이 나와버릴 때 제대로 표현할수 없겠죠.

음수의 경우에는 sign bit 을 쓰던 2's complement 를 쓰던
하면 양수가 되는거니까 음수로 너무 작아서 문제가 되는 경우도
overflow 라고 합니다.

개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?

cdpark의 이미지

char c1 = 0xcd;

이 문장은 c1 = -51이라는 뜻이죠.

C 언어에서 함수의 argument로 char를 넘길 때는 자동으로 int로 바뀝니다. 이때, singed char는 signed int로, unsigned char는 unsigned int로 바뀌어 넘어가고요.

printf에서 ffffffcd 값이 찍힌 건, signed int -51 값을 hex로 찍은 것입니다.

winner의 이미지

정수진급이라고 번역하죠.

int 의 표현범위 안에 있는 integral type(정수형)들은 int 로 처리됩니다.

jinushun의 이미지

그렇군요.
오버플로랑은 상관없군요..

그래서 플그램짤때 메모리는 안딸리는 -_- 세상이니깐

워드크기로 잡고 하란말을 자주 들었습니다.

ㅎㅎ

좋은 가르침 감사합니다.

----------------------------
www.nate.com
----------------------------

girneter의 이미지

cdpark wrote:
char c1 = 0xcd;

이 문장은 c1 = -51이라는 뜻이죠.

C 언어에서 함수의 argument로 char를 넘길 때는 자동으로 int로 바뀝니다. 이때, singed char는 signed int로, unsigned char는 unsigned int로 바뀌어 넘어가고요.

printf에서 ffffffcd 값이 찍힌 건, signed int -51 값을 hex로 찍은 것입니다.

integral promotion 에서 엄밀히 말하면
unsigned char 도 int 로 넘어가는게 맞습니다.

D&R 책에 보면
char 가 signed 이든 unsigned 이든
int type 의 표현한계내에 있다면 int 로 변환한다
그렇게 되어 있지요.

결과적으로는 같은 거지만...

개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?

datamind의 이미지

예제입니다.
오버플로우는 a << 1 하다가 발생하고,
언더플로우는 a >> 1 하다가 발생을 합니다.

overflow()
{
    char a=0, b;

    b = a;
    while(1) {
        a += 1;
        if( a > b ) {     
            printf("ok a=%d\n", a );
        }
        else {  // 순간 b 가 더 커집니다. 
            printf("overflow !!\n");
            return;
        }
        b = a;
    }
}

underflow()
{
    double a = 1, b;

    b = a;
    while(1) {
        a /= 2;   
        if( a < b ) {
            printf("ok a=%g\n", a );
        }
        else {   
            // 순간 a 가 커집니다.  0 이 되기 때문이죠
            // 실수 정밀도의 한계땜시 발생을 하는 거겠죠... -_-;;
            printf("underflow !!!\n");
            return;
        }
        b = a;
    }
}

main()
{
    overflow();
    underflow();   
}
moonzoo의 이미지

아하.char 형을 인자로 넘길때 int 형으로 처리해서 그런거군요~

답변 감사합니다.

bh의 이미지

모두 감사합니다..

--
이 아이디는 이제 쓰이지 않습니다.

luckyjc7의 이미지

굉장히 오래된 포스트네요..조금만더 덧붙이자면

오버플로우는 "연산 결과 값이 해당자료 형의 범위를 넘어서는 경우" 입니다.

양수와 양수를 더했는데 음수가 출력되는 경우
음수와 음수를 더했는데 양수가 출력되는 경우 죠.

위 의 코드에서

char c1 = 0xcd;

는 오버플로우는 아니죠.
signed char 이므로 -128 ~ 127 의 범위를 표현할 수 있고, c1에는 -51 의 값이 저장되어 있는 거니까요.

참고로 char이 문자를 표현하는 자료형으로 사용될 때, signed 8bit 변수 임에도 불구하고 ascii 코드가 0~128 까지만 있는건 상위 1비트를 패리티 비트로 사용하기 때문입니다.
(확장 ascii에서는 더 많은 범위를 지원하죠)

예전에 이 문제 때문에 과제하다가 몇 시간을 날려 먹은적이 있어서 기억이 나네요ㅡ..ㅡ

planetarium의 이미지

글쎄요. 어차피 이왕에 올라왔으니...
딱히 연산의 결과가 아니더라도 입력을 받아들이지 못하면 다 오버플로우라고 봐야하지 않을까요.
0xcd가 좀 애매해보이지만, 그럼
short n = 1000000; 이것도 오버플로우가 아닌가요?

luckyjc7의 이미지

3달만에 답글을 확인하네요^^;

short n = 1000000;

도 오버플로우 입니다.
대입 연산의 결과가 자료형의 범위를 넘어서네요.

제 말도 '입력을 다 받아들이지 못하면 오버플로우' 라는 것과 일맥 상통합니다만..
음..이전 글에서 음수와 양수의 덧셈 이야기는 예로 든 것이었습니다.

한가지 예를 들겠습니다.
gcc 4.4.5 기준입니다.

unsigned int si_2 = 0xFFFFFFFF;
unsigned int si_3 = 0x00000001;
unsigned long long int si_4 = si_2 + si_3;
printf("%llu\n",si_4);

위 의 결과값은 0x100000000 이 아니라, 0x0 입니다.

si_2 + si_3을 연산 결과가 overflow입니다. '32bit 부호없는 정수' 의 범위를 넘어서니까요.
그리고 si_4 에는 0x0 가 대입이 되죠.

unsigned int si_2 = 0xFFFFFFFF;
unsigned int si_3 = 0x00000001;
unsigned long long int si_4 = (unsigned long long int)si_2 + (unsigned int long long)si_3;
printf("%llu\n",si_4);

위의 결과는 0x100000000 입니다.
si_2와 si_3가 '64bit 부호없는 정수' 로 캐스팅 되면서 오버플로우가 일어나지 않죠.

short int의 경우를 위의 예에 똑같이 적용해 보면.. 이야기가 .. 좀 다르네요. 오버플로우가 일어나지 않습니다.
기본적으로 32bit 레지스터를 이용해서 연산을 하기 때문에 오버플로우가 일어나지 않는 듯 합니다.
이경우는 제가 생각 했던 것과 좀 다르군요.. 하하^^;;

오버플로우는 'hardware 레벨에서의 연산 결과 상태 중의 하나' 라고 볼 수 있겠네요..

이상 허접한 답변이었습니다.

kaeri17의 이미지

overflow라고 보기에는 0xcd자체가 10진수로 읽히는 것 보다는 메모리의 초기값을 주는 것의 의미기 때문에 sign extension으로 생각하는게 나을듯 합니다.

댓글 달기

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