>  기사  >  백엔드 개발  >  ## 오른쪽 Shift 연산자가 큰 Shift 값에서 예기치 않은 동작을 나타내는 이유는 무엇입니까?

## 오른쪽 Shift 연산자가 큰 Shift 값에서 예기치 않은 동작을 나타내는 이유는 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-10-26 06:29:30576검색

## Why Does the Right Shift Operator Exhibit Unexpected Behavior with Large Shift Values?

오른쪽 시프트 연산자의 흥미로운 동작

오른쪽 시프트 연산자(>>)는 큰 오른쪽 시프트 값을 처리할 때 특이한 동작을 나타냅니다. . 다음 프로그램을 고려해 보세요.

<code class="c++">#include <iostream>
#include <stdint.h>

int foo(int a, int b)
{
   return a >> b;
}

int bar(uint64_t a, int b)
{
   return a >> b;
}

int main()
{
    std::cout << "foo(1, 32): " << foo(1, 32) << std::endl;
    std::cout << "bar(1, 32): " << bar(1, 32) << std::endl;
    std::cout << "1 >> 32: " << (1 >> 32) << std::endl; //warning
    std::cout << "(int)1 >> (int)32: " << ((int)1 >> (int)32) << std::endl; //warning
}

foo(1, 32)의 예상 출력은 0이지만 놀랍게도 1을 반환합니다. 이는 다음과 같은 이유 때문일 수 있습니다.

논리적 시프트 대 산술 시프트

x86/x86-64 아키텍처에서 오른쪽 시프트 연산자는 실제로 논리적 오른쪽 시프트를 수행합니다. 왼쪽 피연산자의 부호에 관계없이 비트가 0입니다. 동작은 >>>를 사용하는 것과 유사합니다. b.

컴파일러 최적화

foo(1, 32)의 경우 값 32가 int로 캐스팅되어 효과적으로 32비트로 잘립니다. int가 보유할 수 있는 최대값은 231-1이므로 오른쪽 시프트는 본질적으로 >>> (32 % 32), 이는 0으로 평가됩니다.

정의되지 않은 동작

관련 C 표준에서는 개수가 더 큰 오른쪽 시프트에 대해 "동작이 정의되지 않음"이라고 명시합니다. 승격된 왼쪽 피연산자의 너비보다 크거나 같습니다. 이 경우, 1>> 32 및 (int)1>> (int)32의 개수가 32보다 크므로 예측할 수 없는 결과가 발생합니다.

bar(1, 32)와의 차이점

함수 bar는 64비트를 사용합니다. 너비가 32보다 큰 것이 보장되는 부호 없는 정수입니다. 따라서 bar의 오른쪽 시프트는 정의되지 않은 동작의 영향을 받지 않습니다.

결론

의 동작 큰 시프트 값을 처리할 때 오른쪽 시프트 연산자가 모호해집니다. x86/x86-64 아키텍처에서는 논리적 오른쪽 시프트가 수행되는 반면 ARM에서는 다른 구현이 사용될 수 있습니다. 정의되지 않은 동작으로 인해 피연산자 너비보다 크거나 같은 개수의 오른쪽 시프트 결과는 이식 가능한 코드에서 피해야 합니다.

위 내용은 ## 오른쪽 Shift 연산자가 큰 Shift 값에서 예기치 않은 동작을 나타내는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.