동일한 쉬프트 연산이나, 값들이 다른 이유를 알 수 있나요?

ikpil의 이미지

				char c1 = char('c' << 2) >> 2;
				char c2 = unsigned char('c' << 2) >> 2;
				char c3 = ('c' << 2) >> 2;

인코딩으로 인해, 쉬프트 연산을 하였습니다만, 궁금한 점을 발견하여
질문을 올리게 됩니다.

질문
1. 연산은 똑같은데 왜 각각의 값들이 다를까요?(c1, c2, c3 )

haze11의 이미지

ikpil의 이미지

직접 컴파일 해 보시면 다른것을 알 수 있으실 것입니다.

http://www.ikpil.com

grassman의 이미지

C 언어에서 unsigned type에 대한 shift 연산은 logical shift를 합니다.
반면 signed type의 경우 arithmetic shift를 수행합니다.

소스 코드에서 char() 부분이나 unsigned char() 부분은 type cast에 대한
오타인 것 같으니 무시하고 설명하겠습니다.

c1의 경우 'c' << 2를 계산하면 0x18c입니다. signed char로 type cast를 하면 0x8c가 되고 이것을
arithmetic shift로 계산하면 0xe3가 됩니다.

c2의 경우 unsigned char로의 type cast로 인해 마지막 shift 연산이 logical shift로 바뀝니다.
결과는 0x23이 됩니다.

c3의 경우 중간 과정에서 integer로 변환되어 계산되고 있었으므로 모든 계산값이 보존됩니다.
연산은 arithmetic shift이지만 integer형의 범위에서는 계산값이 MSB에 영향을 주지 않으므로
원래 값인 0x63으로 나타납니다.

ikpil의 이미지

타입 캐스트 오타 아닙니다. 타입 캐스팅의 3가지 방법중 한가지 방법 입니다. : )
참고로 C++ 입니다.

그리고.. 명쾌한 답변 감사합니다!

http://www.ikpil.com

grassman의 이미지

임시 객체 생성을 통한 type cast 효과로군요.
C++는 거의 안쓰다 보니 생소하네요.

bootmeta의 이미지

결과는 compiler 의존적입니다.

일반적으로 signed type의 경우 arithmetic shift(연산입니다만, <<냐 >>냐에 따라 다를 수도 있고, 심지어 전부 logical shfit일 수도 있습니다.(일반적인 경우때문에 arithmetic shift를 signed shift라고 불리기도 합니다.)

bitwise연산을 할때는 사용 compiler에 주의해서 작업해야 합니다.

ps)
추가로 gcc의 경우 음수 표현은 2의 보수형태이나, compiler마다 다를 수 있습니다.
제가 알기로 C 표준에서도 명확하게 정의가 안되어 있는 것으로 알고 있습니다.(잘못 알고 있는 건지도 --;)

grassman의 이미지

표준에서 shift 연산의 구현은 implementation-defined로 나타나 있습니다.
원칙적으로 이 부분은 컴파일러의 reference manual을 참조하는 것이 맞습니다.

다만 질문의 상황이 x86이나 ARM 같은 범용 프로세서에서의 상황인듯 하여 2의 보수법을
사용하는 CPU에 대한 일반적인 컴파일러 구현을 가정하여 답변한 것입니다.

ikpil의 이미지

이 글을 읽고 모든 플랫폼에서 잘 돌아가게 할라면
unsigned 로 만들어서 돌려야 하는 것을 알았습니다.

감사합니다!

http://www.ikpil.com

ikpil의 이미지

감사합니다 좋은 정보 알아 갑니다.

http://www.ikpil.com

댓글 달기

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