비트 시프트는 값을 숫자 수량이 아닌 일련의 비트로 취급하기 때문에 비트 연산으로 간주되는 경우가 있습니다. 이 작업에서 숫자는 왼쪽 또는 오른쪽으로 이동하거나 이동합니다. 컴퓨터 프로세서의 레지스터는 고정 너비를 가지므로 일부 비트는 한쪽 끝에서 레지스터에서”이동”되는 반면 동일한 수의 비트는 다른 쪽 끝에서”이동”됩니다.
비트 주소 지정편집
레지스터의 너비(자주 32 또는 심지어 64)가 자주 바이트라고 불리는 가장 작은 주소 지정 가능한 단위(원자 요소)의 비트 수(일반적으로 8)보다 크면 시프트 연산은 비트에 주소 지정 방식을 유도합니다.레지스터의 양쪽 끝에서 경계 효과를 무시하면 산술 및 논리 시프트 연산이 동일하게 작동하며 8 비트 위치에 의한 시프트는 다음과 같은 방식으로 비트 패턴을 1 바이트 위치로 전송합니다:
|
8 개의 위치에 의하여 좌 교대는 바이트 주소를 곁에 증가합니다 1 |
|
8 개의 위치에 의하여 적당한 교대는 바이트 주소를 곁에 줄입니다 1 |
|
8 개의 위치에 의하여 좌 교대는 바이트 주소를 곁에 줄입니다 1 |
|
8 개의 위치에 의하여 적당한 교대는 바이트 주소를 곁에 증가합니다 1 |
산술 이동편집
산술 이동에서는 양쪽 끝에서 이동된 비트가 삭제됩니다. 왼쪽 산술 시프트에서는 오른쪽에서 0 이 시프트됩니다; 오른쪽 산술 시프트에서는 기호 비트(2 의 보수 값)가 왼쪽에 시프트되어 피연산자의 부호가 유지됩니다.
이 예제에서는 2 의 보수로 해석되는 8 비트 레지스터를 사용합니다:
00010111 (decimal +23) LEFT-SHIFT= 00101110 (decimal +46)
10010111 (decimal −105) RIGHT-SHIFT= 11001011 (decimal −53)
첫 번째 경우에는 가장 왼쪽 숫자가 레지스터의 끝을 지나서 이동되고 새로운 0 이 가장 오른쪽 위치로 이동되었습니다. 두 번째 경우에는 가장 오른쪽 1 이 밖으로 옮겨졌고(아마도 캐리 플래그로)새로운 1 이 가장 왼쪽 위치로 복사되어 숫자의 부호가 보존되었습니다. 여러 교대는 때때로 숫자의 일부 숫자로 하나의 변화로 단축된다. 예를 들어:
00010111 (decimal +23) LEFT-SHIFT-BY-TWO= 01011100 (decimal +92)
왼쪽 산술 시프트 에 의해 엔 2 를 곱하는 것과 같습니다 엔(값이 오버플로되지 않는 경우),반면 오른쪽 산술 시프트 에 의해 엔 2 의 보수 값은 2 로 나눈 것과 같습니다 엔 음의 무한대로 반올림합니다. 2 진수가 1 의 보수로 처리되면 동일한 오른쪽 시프트 연산으로 인해 2 로 나누어지고 0 으로 반올림됩니다.
논리 시프트
왼쪽 논리 시프트
|
오른쪽 논리 시프트
|
논리 시프트에서 0 은 삭제된 비트를 대체하기 위해 시프트됩니다. 따라서 논리 및 산술 왼쪽 교대는 정확히 동일합니다.
그러나 논리 오른쪽 시프트가 값 0 비트를 가장 중요한 비트에 삽입하므로 부호 비트를 복사하는 대신 부호없는 이진수에 이상적이며 산술 오른쪽 시프트는 부호있는 2 의 보수 이진수에 이상적입니다.
추가 정보:원형 시프트
또 다른 형태의 시프트는 원형 시프트,비트 회전 또는 비트 회전이다.
회전편집
왼쪽 원형 이동 또는 회전
|
오른쪽 원형 이동 또는 회전
|
이 작업에서 때로는 회전 없음 캐리라고하며 비트는 레지스터의 왼쪽 및 오른쪽 끝이 결합 된 것처럼”회전”됩니다. 왼쪽 시프트 중에 오른쪽으로 시프트되는 값은 왼쪽에서 시프트된 값이며 오른쪽 시프트 작업의 경우 그 반대의 경우도 마찬가지입니다. 이 기능은 기존의 모든 비트를 유지해야 하며 디지털 암호화에 자주 사용되는 경우에 유용합니다.
캐리편집
왼쪽 회전 통해 캐리
|
오른쪽 회전 통해 수행
|
캐리를 통해 회전(양쪽 끝)에서 이동되는 비트가 캐리 플래그의 이전 값이고,(다른 쪽 끝)밖으로 이동되는 비트가 캐리 플래그의 새 값이되는 회전 작업의 변형입니다.
캐리 스루 단일 회전은 캐리 플래그를 미리 설정하여 한 위치의 논리 또는 산술 시프트를 시뮬레이션 할 수 있습니다. 예를 들어,캐리 플래그가 0 을 포함하는 경우x RIGHT-ROTATE-THROUGH-CARRY-BY-ONE
은 논리적 오른쪽 이동이고 캐리 플래그가 부호 비트의 복사본을 포함하는 경우x RIGHT-ROTATE-THROUGH-CARRY-BY-ONE
은 산술 오른쪽 이동입니다. 이러한 이유로 로우 엔드 갤러리와 같은 일부 마이크로 컨트롤러는 캐리를 통해 회전 및 회전하며 산술 또는 논리 시프트 지침을 귀찮게하지 않습니다.
캐리를 통한 회전은 프로세서의 네이티브 워드 크기보다 큰 숫자에서 시프트를 수행할 때 특히 유용합니다. 회전-스루-캐리,그 비트는 여분의 준비없이 두 번째 시프트 동안 이동 준비,첫 번째 시프트 동안 캐리 플래그에”저장”됩니다.
고급 언어편집
<<
“이고 오른쪽 시프트의 경우”>>
“입니다. 이동할 장소 수는 연산자의 두 번째 인수로 지정됩니다. 예를 들어,
x = y << 2;
x
에y
를 왼쪽으로 2 비트로 이동 한 결과를 할당합니다.이 결과는 4 의 곱셈과 같습니다.
교대는 구현 정의 동작 또는 정의되지 않은 동작을 초래할 수 있으므로 교대를 사용할 때는 주의해야 합니다. 단어의 크기보다 크거나 같은 비트 수로 이동 한 결과는 정의되지 않은 동작 씨 과 씨++. 부호있는 값을 왼쪽으로 옮기는 결과는 결과 형식으로 표시할 수 없는 경우 정의되지 않습니다.
기음#에서 오른쪽 시프트는 첫 번째 피연산자가 지능 또는 긴 경우 산술 시프트입니다. 첫 번째 피연산자 유형이 유니트 또는 울롱 인 경우 오른쪽 시프트는 논리적 시프트입니다.회전 연산자가 없지만 시프트 연산자에서 합성할 수 있습니다. 보안 요구 사항이 있는 소프트웨어에서 정의되지 않은 동작 및 타이밍 공격을 피하기 위해 명령문이 제대로 작성되었는지 확인해야 합니다. 예를 들어,부호없는 32 비트 값x
를n
위치로 왼쪽으로 회전시키는 순진한 구현은 다음과 같습니다:
uint32_t x = ..., n = ...;uint32_t y = (x << n) | (x >> (32 - n));
그러나0
비트에 의한 시프트는32 - 0
가32
이고32
가범위를 벗어나기 때문에
(x >> (32 - n))
오른손 식에서 정의되지 않은 동작이 발생합니다. 두 번째 시도에서 발생할 수 있습니다:
uint32_t x = ..., n = ...;uint32_t y = n ? (x << n) | (x >> (32 - n)) : x;
시프트 양이 정의되지 않은 동작을 도입하지 않도록하기 위해 테스트되는 경우. 그러나 분기는 추가 코드 경로를 추가하고 타이밍 분석 및 공격 기회를 제공하며 이는 고 무결성 소프트웨어에서는 허용되지 않는 경우가 많습니다. 또한 코드는 여러 컴퓨터 명령어로 컴파일되며,이는 종종 프로세서의 기본 명령어보다 효율적이지 않습니다.
정의되지 않은 동작과 분기를 피하려면 다음을 권장합니다. 이 패턴은 많은 컴파일러에서 인식되며 컴파일러는 단일 회전 명령을 방출합니다:
uint32_t x = ..., n = ...;uint32_t y = (x << n) | (x >> (-n & 31));
순환 시프트를 구현하는 컴파일러 별 내장 함수도 있습니다. 그 소리는 위의 문제를 겪고 마이크로 소프트의 호환성에 대한 몇 가지 회전 내장 함수를 제공합니다. 회전 내장 함수를 제공하지 않습니다. 인텔은 또한 86 내장 함수를 제공합니다.
자바에딧
자바에서는 모든 정수 유형이 부호화되어 있으므로”<<
“및”>>
“연산자는 산술 시프트를 수행합니다. 자바는 논리 오른쪽 시프트를 수행하기 위해 연산자”>>>
“를 추가하지만 논리 및 산술 왼쪽 시프트 연산은 부호있는 정수에 대해 동일하기 때문에 자바에는”<<<
“연산자가 없습니다.
자바 시프트 연산자의 자세한 내용:
- 연산자
<<
(왼쪽 시프트),>>
(부호있는 오른쪽 시프트)및>>>
(부호없는 오른쪽 시프트)를 시프트 연산자라고합니다. - 시프트 식의 형식은 왼쪽 피연산자의 승격된 형식입니다. 예를 들어
aByte >>> 2
은와 같습니다.) >>> 2
. - 왼쪽 피연산자의 승격된 형식이 지능이면 오른쪽 피연산자의 5 개의 최하위 비트만 이동 거리로 사용됩니다. 마치 오른쪽 피연산자가 비트 논리 및 연산자&를 받는 것과 같습니다. 따라서 실제로 사용되는 시프트 거리는 항상 0 에서 31 까지의 범위에 있습니다.
- 왼쪽 피연산자의 승격된 형식이 긴 경우 오른쪽 피연산자의 6 개의 최하위 비트만 이동 거리로 사용됩니다. 마치 오른쪽 피연산자가 비트 논리 및 연산자&를 받는 것과 같습니다. 따라서 실제로 사용되는 시프트 거리는 항상 0 에서 63 까지의 범위에 있습니다.
엔>>>에스
엔 오른쪽 이동 에스 비트 위치 0 확장.- 비트 및 시프트 작업에서
byte
유형은 암시적으로int
로 변환됩니다. 바이트 값이 음수이면 가장 높은 비트는 1 이고,그 다음 바이트는 지능의 추가 바이트를 채우는 데 사용됩니다. 그래서바이트 b1=-5;int i=b1|0x0200;
에나==-5
.
자바스크립트 편집
자바스크립트에서는 비트 연산을 사용하여 두 개 이상의 각 단위를 1 또는 0 으로 평가합니다.
파스칼 편집
파스칼뿐만 아니라 모든 방언(예:객체 파스칼 및 표준 파스칼)에서 논리적 왼쪽 및 오른쪽 시프트 연산자는 각각”shl
“및”shr
“입니다. 부호있는 정수의 경우에도shr
는 논리적 이동처럼 동작하며 부호 비트를 복사하지 않습니다. 이동할 장소의 수는 두번째 인수로 주어진다. 예를 들어,다음 할당 엑스 시프트의 결과 와이 왼쪽으로 두 비트:
x := y shl 2;