답변:
슈퍼 (아마도 오버) 단순화 된 정의는 <<
"2 배"에 사용되며 "2 >>
로 나누기"에 사용되며 그 이후의 숫자는 몇 번입니다.
그래서 n << x
"n x 2, x x"입니다. 그리고 y >> z
"y를 2로 나눈 값, z 배"입니다.
예를 들어 1 << 5
"1 x 2, 5 x"또는 32입니다. 그리고 32 >> 5
"32를 2로 나누기, 5 x"또는 1입니다.
다른 모든 답변은 더 기술적 인 정의를 제공하지만 아무도 그것을 정말로 퉁명스럽게 배치하지 않았고 나는 당신이 그것을 원할 것이라고 생각했습니다.
http://golang.org/doc/go_spec.html 의 사양에서 적어도 정수의 경우 이진 시프트 인 것 같습니다. 예를 들어, 바이너리 0b00001000 >> 1은 0b00000100이고 0b00001000 << 1은 0b00010000입니다.
Go는 이진 정수에 대해 0b 표기법을 받아들이지 않는 것 같습니다. 나는 단지 예를 위해 그것을 사용하고 있었다. 십진수에서 8 >> 1은 4이고 8 << 1은 16입니다. 왼쪽으로 1만큼 이동하는 것은 2로 곱하는 것과 같고 오른쪽으로 1로 이동하는 것은 2로 나누고 나머지를 버리는 것과 같습니다.
<< 및 >> 연산자는 Go 산술 연산자 입니다.
<< left shift integer << unsigned integer
>> right shift integer >> unsigned integer
시프트 연산자는 오른쪽 피연산자로 지정된 시프트 카운트만큼 왼쪽 피연산자를 시프트합니다. 왼쪽 피연산자가 부호있는 정수이면 산술 시프트를 구현하고 부호없는 정수이면 논리 시프트를 구현합니다. 시프트 카운트는 부호없는 정수 여야합니다. 시프트 수에는 상한이 없습니다. 시프트는 시프트 카운트 n에 대해 왼쪽 피연산자가 1 씩 n 번 시프트 된 것처럼 작동합니다. 결과적으로 x << 1은 x * 2와 같고 x >> 1은 x / 2와 같지만 음의 무한대로 잘립니다.
그것들은 기본적으로 산술 연산자 이며 다른 언어에서도 마찬가지입니다. 여기에 기본 PHP, C, Go 예제가 있습니다.
가다
package main
import (
"fmt"
)
func main() {
var t , i uint
t , i = 1 , 1
for i = 1 ; i < 10 ; i++ {
fmt.Printf("%d << %d = %d \n", t , i , t<<i)
}
fmt.Println()
t = 512
for i = 1 ; i < 10 ; i++ {
fmt.Printf("%d >> %d = %d \n", t , i , t>>i)
}
}
씨
#include <stdio.h>
int main()
{
int t = 1 ;
int i = 1 ;
for(i = 1; i < 10; i++) {
printf("%d << %d = %d \n", t, i, t << i);
}
printf("\n");
t = 512;
for(i = 1; i < 10; i++) {
printf("%d >> %d = %d \n", t, i, t >> i);
}
return 0;
}
PHP
$t = $i = 1;
for($i = 1; $i < 10; $i++) {
printf("%d << %d = %d \n", $t, $i, $t << $i);
}
print PHP_EOL;
$t = 512;
for($i = 1; $i < 10; $i++) {
printf("%d >> %d = %d \n", $t, $i, $t >> $i);
}
그들은 모두 출력합니다
1 << 1 = 2
1 << 2 = 4
1 << 3 = 8
1 << 4 = 16
1 << 5 = 32
1 << 6 = 64
1 << 7 = 128
1 << 8 = 256
1 << 9 = 512
512 >> 1 = 256
512 >> 2 = 128
512 >> 3 = 64
512 >> 4 = 32
512 >> 5 = 16
512 >> 6 = 8
512 >> 7 = 4
512 >> 8 = 2
512 >> 9 = 1
Go의 << 및 >>는 다른 언어의 교대 (즉, 2의 거듭 제곱으로 나누기 또는 곱하기)와 유사하지만 Go는 C / C ++보다 안전한 언어이기 때문에 교대 횟수가 숫자 일 때 추가 작업을 수행합니다. .
x86 CPU의 시프트 명령어는 시프트 수의 5 비트 (64 비트 x86 CPU에서는 6 비트) 만 고려합니다. C / C ++와 같은 언어에서 시프트 연산자는 단일 CPU 명령어로 변환됩니다.
다음 Go 코드
x := 10
y := uint(1025) // A big shift count
println(x >> y)
println(x << y)
인쇄물
0
0
C / C ++ 프로그램이 인쇄하는 동안
5
20
<<
왼쪽 교대입니다. >>
왼쪽 피연산자가 부호있는 정수이면 부호 확장 오른쪽 시프트이고 왼쪽 피연산자가 부호없는 정수이면 0 확장 오른쪽 시프트입니다.
더 잘 이해하기 위해 >>
생각
var u uint32 = 0x80000000;
var i int32 = -2;
u >> 1; // Is 0x40000000 similar to >>> in Java
i >> 1; // Is -1 similar to >> in Java
따라서 부호없는 정수에 적용하면 왼쪽에있는 비트는 0으로 채워지고, 부호있는 정수에 적용되면 왼쪽에있는 비트는 가장 왼쪽에있는 비트로 채워집니다 (부호가있는 정수가 2에 따라 음수 일 때 1). 보어).