일반적으로 signed type의 경우 arithmetic shift(연산입니다만, <<냐 >>냐에 따라 다를 수도 있고, 심지어 전부 logical shfit일 수도 있습니다.(일반적인 경우때문에 arithmetic shift를 signed shift라고 불리기도 합니다.)
bitwise연산을 할때는 사용 compiler에 주의해서 작업해야 합니다.
ps)
추가로 gcc의 경우 음수 표현은 2의 보수형태이나, compiler마다 다를 수 있습니다.
제가 알기로 C 표준에서도 명확하게 정의가 안되어 있는 것으로 알고 있습니다.(잘못 알고 있는 건지도 --;)
http://codepad.org/sXlF0y5f
http://codepad.org/sXlF0y5f
같은데요?
직접 컴파일 해
직접 컴파일 해 보시면 다른것을 알 수 있으실 것입니다.
http://www.ikpil.com
http://www.ikpil.com
arithmetic shift와 logical shift의 차이입니다.
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으로 나타납니다.
타입 캐스트 오타
타입 캐스트 오타 아닙니다. 타입 캐스팅의 3가지 방법중 한가지 방법 입니다. : )
참고로 C++ 입니다.
그리고.. 명쾌한 답변 감사합니다!
http://www.ikpil.com
http://www.ikpil.com
그렇군요.
임시 객체 생성을 통한 type cast 효과로군요.
C++는 거의 안쓰다 보니 생소하네요.
grassman 댓글에 추가로
결과는 compiler 의존적입니다.
일반적으로 signed type의 경우 arithmetic shift(연산입니다만, <<냐 >>냐에 따라 다를 수도 있고, 심지어 전부 logical shfit일 수도 있습니다.(일반적인 경우때문에 arithmetic shift를 signed shift라고 불리기도 합니다.)
bitwise연산을 할때는 사용 compiler에 주의해서 작업해야 합니다.
ps)
추가로 gcc의 경우 음수 표현은 2의 보수형태이나, compiler마다 다를 수 있습니다.
제가 알기로 C 표준에서도 명확하게 정의가 안되어 있는 것으로 알고 있습니다.(잘못 알고 있는 건지도 --;)
예. 맞습니다.
표준에서 shift 연산의 구현은 implementation-defined로 나타나 있습니다.
원칙적으로 이 부분은 컴파일러의 reference manual을 참조하는 것이 맞습니다.
다만 질문의 상황이 x86이나 ARM 같은 범용 프로세서에서의 상황인듯 하여 2의 보수법을
사용하는 CPU에 대한 일반적인 컴파일러 구현을 가정하여 답변한 것입니다.
이 글을 읽고 모든
이 글을 읽고 모든 플랫폼에서 잘 돌아가게 할라면
unsigned 로 만들어서 돌려야 하는 것을 알았습니다.
감사합니다!
http://www.ikpil.com
http://www.ikpil.com
감사합니다 좋은
감사합니다 좋은 정보 알아 갑니다.
http://www.ikpil.com
http://www.ikpil.com
댓글 달기