Câu trả lời:
Định nghĩa đơn giản hóa siêu (có thể hơn) chỉ <<
được sử dụng cho "lần 2" và >>
"chia cho 2" - và số sau nó là bao nhiêu lần.
Như vậy n << x
là "n lần 2, x lần". Và y >> z
là "y chia cho 2, z lần".
Ví dụ: 1 << 5
là "1 nhân 2, 5 lần" hoặc 32. Và 32 >> 5
là "32 chia cho 2, 5 lần" hoặc 1.
Tất cả các câu trả lời khác cung cấp định nghĩa kỹ thuật hơn, nhưng không ai đưa ra nó một cách thực sự thẳng thắn và tôi nghĩ bạn có thể muốn điều đó.
Từ thông số kỹ thuật tại http://golang.org/doc/go_spec.html , có vẻ như ít nhất với số nguyên, đó là một dịch chuyển nhị phân. ví dụ: nhị phân 0b00001000 >> 1 sẽ là 0b00000100 và 0b00001000 << 1 sẽ là 0b00010000.
Go dường như không chấp nhận ký hiệu 0b cho số nguyên nhị phân. Tôi chỉ sử dụng nó để làm ví dụ. Trong hệ thập phân, 8 >> 1 là 4, và 8 << 1 là 16. Chuyển sang trái bởi một giống như phép nhân với 2 và chuyển sang phải với một cũng giống như chia cho hai, loại bỏ bất kỳ phần dư nào.
Các toán tử << và >> là các toán tử số học Go .
<< left shift integer << unsigned integer
>> right shift integer >> unsigned integer
Các toán tử shift dịch chuyển toán hạng bên trái bằng số dịch chuyển được chỉ định bởi toán hạng bên phải. Chúng thực hiện dịch chuyển số học nếu toán hạng bên trái là một số nguyên có dấu và dịch chuyển logic nếu nó là một số nguyên không dấu. Số lượng ca phải là một số nguyên không dấu. Không có giới hạn trên về số ca làm việc. Dịch chuyển hoạt động như thể toán hạng bên trái được dịch n lần 1 với số lần dịch chuyển là n. Kết quả là x << 1 giống với x * 2 và x >> 1 giống với x / 2 nhưng bị cắt bớt về phía âm vô cùng.
Về cơ bản chúng là các toán tử số học và nó giống nhau trong các ngôn ngữ khác ở đây là ví dụ cơ bản về PHP, C, Go
ĐI
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)
}
}
C
#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);
}
Tất cả họ sẽ xuất
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
<< và >> của Go tương tự như shift (nghĩa là: chia hoặc nhân với lũy thừa 2) trong các ngôn ngữ khác, nhưng vì Go là ngôn ngữ an toàn hơn C / C ++ nên nó thực hiện một số công việc bổ sung khi số shift là một số .
Lệnh shift trong CPU x86 chỉ xem xét 5 bit (6 bit trên CPU x86 64 bit) của số lượng shift. Trong các ngôn ngữ như C / C ++, toán tử shift sẽ chuyển thành một lệnh CPU duy nhất.
Mã Go sau
x := 10
y := uint(1025) // A big shift count
println(x >> y)
println(x << y)
bản in
0
0
trong khi một chương trình C / C ++ sẽ in
5
20
<<
là dịch trái. >>
là dịch chuyển sang phải mở rộng dấu khi toán hạng bên trái là số nguyên có dấu và là dịch chuyển sang phải mở rộng bằng 0 khi toán hạng bên trái là số nguyên không dấu.
Để hiểu rõ hơn, >>
hãy nghĩ về
var u uint32 = 0x80000000;
var i int32 = -2;
u >> 1; // Is 0x40000000 similar to >>> in Java
i >> 1; // Is -1 similar to >> in Java
Vì vậy, khi áp dụng cho một số nguyên không dấu, các bit ở bên trái được điền bằng 0, trong khi khi áp dụng cho một số nguyên có dấu, các bit ở bên trái được lấp đầy bằng bit ngoài cùng bên trái (là 1 khi số nguyên có dấu là âm trên 2 của bổ sung).
Trong toán học thập phân , khi chúng ta nhân hoặc chia cho 10 , chúng ta sẽ tính các số không ở cuối số.
Trong hệ nhị phân , 2 có cùng tác dụng. Vì vậy, chúng tôi đang thêm một số 0 vào cuối hoặc xóa chữ số cuối cùng