Bit shifting 질문

yeilho의 이미지

64비트로 포팅하는 문서를 보는데 예제가 있어서 따라 해보았더니 다른 결과가 나오네요...

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
 
ptrdiff_t SetBitN(ptrdiff_t value, unsigned bitNum)
{
    ptrdiff_t mask = 1 << bitNum;
    return value | mask;
}
 
int main()
{
    ptrdiff_t num = SetBitN(0, 32);
    printf("num: %lld\n", num);
}

문서에는 '0' 이 나온다고 했는데 정작 돌려보니 '1' 이 나오네요. 비트가 circular된것 같은데 왜 그런지 잘 모르겠네요.

아시는 분 조언 부탁드립니다.

참고로 문서 URL입니다.
http://www.viva64.com/content/articles/64-bit-development/?f=20_issues_of_porting_C++_code_on_the_64-bit_platform.html&lang=en&content=64-bit-development

어찌되었든 문서가 좋습니다.

cppig1995의 이미지

C 표준 6.5.7.3에는 다음과 같은 말이 있습니다.

ISO/IEC 9899:1999 wrote:
6.5.7 Bitwise shift operators
3 [...] If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

많은 환경에서 ptrdiff_t의 크기는 32비트이므로, 1 << 32라는 연산 자체가 정의되지 않은 행동을 보입니다. 다양한 경우를 테스트해 보시면 실제로 비트가 순환되는 것인지 확인하실 수 있을 거라 생각합니다.

> What is the difference between software and hard water?
} Bugs drown in hard water, but live forever in software.

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

lifthrasiir의 이미지

64비트 환경에서는 포인터가 64비트이기 때문에 ptrdiff_t도 64비트입니다. (왜 그럴까요?) 물론 링크된 글에서도 언급되었듯 정수 리터럴 1의 타입은 int이지 ptrdiff_t가 아닙니다.

cppig1995의 이미지

그러게 말이죠. 링크된 원문을 대충 읽다가 { ptrdiff_t | 32 | 64 } 행을 보고 심하게 착각을 했나 봅니다.
이거 참 double x = 2 / 3;스러운 실수군요.

> What is the difference between software and hard water?
} Bugs drown in hard water, but live forever in software.

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

lifthrasiir의 이미지

x86/x86-64 환경에서 x가 32비트일 경우 컴파일러 구현을 간편하게 하기 위해 (x << n)은 (x << (n%32))와 같은 동작을 하는 경우가 많습니다. 따라서 주어진 코드는 (x << 0), 즉 x와 동일해집니다. 물론 앞 답글에서 언급되었듯 언제고 달라질 수 있으므로 이 동작에 의존하지 않는 게 좋습니다.

댓글 달기

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