[완료]쉬프트 연산 질문 드립니다.

Fe.head의 이미지

예상 했던 결과 값이 안나오고 이상한 값이 나오는데요.

이거 왜 그럴까요?

// n.cpp
#include <stdio.h>
 
typedef unsigned long   DWORD;
 
int main()
{
    int     sht = 32;
    DWORD   x = DWORD(-1) >> sht;
 
    printf( "%#x\n", x );
 
    return 0;
}

결과값

0xffffffff

제가 예상하는 값은 0 인데요.
요상하게 0xffff ffff 가 들어가 있네요.
혹시나 해서 어셈블리 코드를 봐보니.

shr eax,cl

이렇게 되어있어서 확실히 산술 쉬프트 연산이 아닌 일반 쉬프트 연산인데 말입니다.

어셈블리 코드.

DWORD   x = DWORD(-1) >> sht;
00411A81  or          eax,0FFFFFFFFh 
00411A84  mov         ecx,dword ptr [sht] 
00411A87  shr         eax,cl 
00411A89  mov         dword ptr [x],eax 

0xffff ffff >> 32 가 왜 0xffff ffff 인지 아리송 합니다.

seoleda의 이미지

진짜 이상하네요. ^^

int sht = 16;
DWORD x = DWORD(-1) >> sht >> sht;
printf( "%#x\n", x );

랑 뭐가 다를까요?
이넘은 예상한 대로 나옵니다.
단지 쉬프트를 한번 더했을 뿐인데...

체스맨의 이미지

좌쉬프트든 우쉬프트든 n 비트인 경우 n-1 까지만 유효하고 초과되면 undefined 일 겁니다. 다음과 같은 경우도 0 이 되어야 할 것 같지만, 이건 undefined 입니다.

unsigned val = 0xffffffffUL>>100 /* undefined */

그래서, 32 비트면 0 ~ 31 비트 쉬프트까지 (총 32가지수) 만 유효합니다.

Orion Project : http://orionids.org

Fe.head의 이미지

그렇군요. 감사합니다.^^

좋은 하루 되세요^^
-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

체스맨의 이미지

음... 제 답변에 일부 오류가 있습니다. 다음 사이트에 좀 더 정확히 정의되어 있네요.
http://msdn2.microsoft.com/en-us/library/f96c63ed(vs.80).aspx

The result of a shift operation is undefined if the second operand is negative, or if the right operand is greater than or equal to the width in bits of the <span>promoted</span> left operand.

'프로모션된 정수의 비트수보다 크거나 같을 때' 이므로, 다음과 같은 경우는 0이 나옵니다.

unsigned char val = 0xff;
unsigned char shifted = val>>8;

하지만, 위 경우도 unsigned (unsigned char 가 프로모션된 정수) 가 32 비트인경우, 32비트 또는 그 이상 우쉬프트하면 undefined 입니다.

Orion Project : http://orionids.org

익명 사용자의 이미지

SHR, SAR, SHL, SAL 명령의 shift count 값이 32비트 모드의 경우에는 5 bit만 mask 된다고 되어 있군요. 따라서 32비트 모드일 때는 shift count 값에 무조건 AND 31 연산을 한 것과 같은 결과가 나오게 되는군요.

Quote:

The destination operand can be a register or a memory location. The count operand
can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits
if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if
64-bit mode and REX.W is used). A special opcode encoding is provided for a count
of 1.

Fe.head의 이미지

답글을 달아 주신분들 감사합니다.

이거 수업시간에 들은기억이 가물가물하게 기억나는군요.

근데 오래되어서 까먹고 있었네요^^

5bit 면
11111 최대 31 이군요.

정말로 33으로 하니까 0x7fff ffff 가 나오는군요.
감사합니다.
-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.