[질문] 음수 표현 방법 / 보수에 관해

kksir의 이미지

안녕하세요.
다음의 코드 결과가 생각하던 것과 달라 당황하고 있습니다 ㅜ.ㅜ

#include <stdio.h>

int main(void)
{
  char a = 7,b=-7,aa,bb;
  char d = 7, dd;

  dd = ~d;

  aa = a>>1;
  bb = b>>1;

  printf("%d %d %d", aa, bb, dd);

  return 0;
}

결과는 3 -4 -8 이 나옵니다.

양수야 그렇다고 쳐도 음수의 경우 정확하게 메모리에는 2의 보수
로 표현되는 줄 알았는데 not 의 경우는 어떻게 되는 것입니까?

kkb110의 이미지

a = 0000 0111 = 7
b = 1111 1001 = -7
d = 0000 0111 = 7

dd = 1111 1000 = -8
aa = 0000 0011 = 3
bb = 1111 1100 = -4

익명 사용자의 이미지

일단 C99 언어 명세서에서는

E1 >> E2에서 E1이 음수일 때, 그 결과값은 구현체가 정의합니다.(implementation-defined).

라 정의하고 있습니다.

실제로 어떻게 될지에 대해서는 여러가지 가능성을 생각해 볼 수 있는데,

1. 왼쪽 빈자리에 무조건 1을 채운다
2. 왼쪽 빈자리에 무조건 0을 채운다
3. 양수이면 0을, 음수이면 1을 채운다.
3. 가장 오른쪽에 있던 bit를 채운다.
4. 우리가 알지 못하는 아ㅤㅎㅐㅎㅤㅎㅐㅎ한 법칙에 의해

등이 가능하겠죠.

일단 implementation-defined라 했으므로 구현자는 이에 대해 어떻게 정의했는지를 문서화할 의무가 있습니다.

Quote:

gcc:
http://gcc.gnu.org/onlinedocs/gcc-3.4.3/gcc/Integers-implementation.html#Integers-implementation

all bit patterns are ordinary values <- 요게 무슨 소리인지는 잘 모르겠군요. 다른 분이 설명해 주시길...

Quote:

MS:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/expre_12.asp

If 0xF000 is unsigned, the result is 0x7800. If 0xF0000000 is signed, a right shift produces 0xF8000000. Shifting a positive number right 32 times produces 0xF0000000. Shifting a negative number right 32 times produces 0xFFFFFFFF.

사용하신 C언어 구현체가 2의 보수 표현법을 사용하고, 맨 앞의 비트를 부호 비트로 사용하고, >> 연산자의 결과가 MS의 방식을 따른다고 가정하고 결과를 해석하자면...

a = 0000 0111
a >> 1 = 0000 0011
3

b = 1111 1001
b >> 1 = 1111 1100
-4

d = 0000 0111
~d = 1111 1000
-8
익명 사용자의 이미지

trap representation:
http://groups.google.com/groups?selm=b7lg1o%24ai4%241%40news.hananet.net

all bit patterns are ordinary values:
직역하면 '모든 비트 패턴이 일반값을 가진다'...인데, 이 ordinary가 단순히 trap representation의 반대말인지 아니면 다른 특별한 의미가 있는 건지는 잘 모르겠습니다. 아시는 분이 추가 답변 달아주시면 감사하겠습니다.

Necromancer의 이미지

음수는

1. 부호비트
2. 1의 보수
3. 2의 보수

지금은 다 2의 보수죠. 회로가 가장 간단하니까요.

부호비트는 최상위 비트가 1이면 그 아랫자리 숫자가 음수가 되는거고
1의 보수는 원수에 NOT을 하면 나옵니다.
(수학적으로 말한다면 원수+보수=2^n -1 의 식이 성립, 단 n은 n비트 영역)
2의 보수는 원수에 NOT한 다음 1을 더하면 나옵니다.
(원수+보수=2^n 입니다)

Written By the Black Knight of Destruction

kksir의 이미지

답변 감사합니다.

a = 0000 0111 
a >> 1 = 0000 0011 
3 

b = 1111 1001 
b >> 1 = 1111 1100 
-4 

d = 0000 0111 
~d = 1111 1000 
-8 

이것을 보면 사실 메모리에 저장될때도 저렇게 되는 건가요?

b 를 보면 1111 1100 인데 어떻게 -4가 되는 지요?
msb인 부호비트를 빼곤 나머지 1 에 관해선 어떻게 해석을
해야 하는지요.

저장 될때 2의 보수로 저장된다면 읽을때는 다시 원수로 바꾸어
줘야 하는 것 아닌가요..

그러면 부호비트까지 바뀌게 될텐데 여기서 부호비트는 안바뀌는지요.

~d 역시 마찬가지 문제가 있고..

::::::::::: Easy come, Different go.
::::::::: Http://www.geekstep.org

정태영의 이미지

kksir wrote:
b 를 보면 1111 1100 인데 어떻게 -4가 되는 지요?
msb인 부호비트를 빼곤 나머지 1 에 관해선 어떻게 해석을
해야 하는지요

보수는 그냥 뒤집고 끝이 아닙니다 :)

1111 1111 은 -1 이지.. 0이 아니거든요
1111 1110 은 -2 이고
1111 1101 은 -3
1111 1100 은 -4 가 되는겁니다..

그렇기 때문에 보수를 만들때는.. 비트를 모두 뒤집어주고.. +1 을 해주게 되죠 =3=33

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

kksir의 이미지

정태영 wrote:
kksir wrote:
b 를 보면 1111 1100 인데 어떻게 -4가 되는 지요?
msb인 부호비트를 빼곤 나머지 1 에 관해선 어떻게 해석을
해야 하는지요

보수는 그냥 뒤집고 끝이 아닙니다 :)

1111 1111 은 -1 이지.. 0이 아니거든요
1111 1110 은 -2 이고
1111 1101 은 -3
1111 1100 은 -4 가 되는겁니다..

그렇기 때문에 보수를 만들때는.. 비트를 모두 뒤집어주고.. +1 을 해주게 되죠 =3=33

네 역수는 1의 보수이고 +1을 하면 2의 보수란걸 몰라서 그런건 아니구요.
1111 1110 이 -2 이면
0000 0001 이 이 수의 1의 보수인가요?
0000 0010 이 이 수의 2의 보수가 되는 건지요?
이때 msb인 부호비트 까지 바뀌는지요?
바뀐다면 양수 2가 되는데..
ㅡㅡ?

::::::::::: Easy come, Different go.
::::::::: Http://www.geekstep.org

익명 사용자의 이미지

일단, 2의 보수니 1의 보수니 하는 문제는 싹 다 잊어버리고, 단지 8개의 비트로 어떻게 자연수를 표현할 것인지를 자유롭게 생각해 보십시오.

일단 세가지 전제조건이 들어갑니다.

1) 부호 비트가 있으면 좋겠다. 일단 양수를 0 음수를 1로 표현한다 가정하자.
2) 크기비교할때의 편의를 위해서 양수끼리, 혹은 음수끼리는 비트 패턴이 연속적이어야 한다(000 0000 < 111 1111 혹은 111 1111 < 000 0000) 오름차순이던 내림차순이던간에...
3) 0은 0000 0000으로 표현한다.

8개의 비트이므로 표현 가능한 경우의 수는 256가지입니다. 그런데 -127 ~ 127은 255가지이므로, 하나가 남습니다. 이걸 -128에 쓰느냐 128에 쓰느냐는 자유이지만, 일단 -128에 쓰도록 합시다.

이제 다시 2의 보수 표기법을 생각합시다.

127 -> 0 111 1111
126 -> 0 111 1110
125 -> 0 111 1101
...
1 -> 0 000 0001
0 -> 0 000 0000
-1 -> 1 111 1111
-2 -> 1 111 1110
...
-126 -> 1 000 0010
-127 -> 1 000 0001
-128 -> 1 000 0000

1의 보수나 부호-크기 표기법이 어떻게 표현될지도 한번 직접 써 보십시오.

댓글 달기

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