Ответы:
Супер (возможно, сверх) упрощенное определение - это просто то, что <<
используется для «умножения на 2» и >>
для «деленного на 2» - и число после него - сколько раз.
Так n << x
и «n раз 2, x раз». И y >> z
это «y делится на 2, z раз».
Например, 1 << 5
«1 умножить на 2,5 раза» или 32. И 32 >> 5
это «32, разделенное на 2, 5 раза» или 1.
Все остальные ответы дают более техническое определение, но никто не изложил его прямо, и я подумал, что вам это может понадобиться.
Из спецификации на http://golang.org/doc/go_spec.html кажется, что, по крайней мере, с целыми числами, это двоичный сдвиг. например, двоичный 0b00001000 >> 1 будет 0b00000100, а 0b00001000 << 1 будет 0b00010000.
Go явно не принимает нотацию 0b для двоичных целых чисел. Я просто использовал это для примера. В десятичном формате 8 >> 1 равно 4, а 8 << 1 равно 16. Сдвиг влево на единицу аналогичен умножению на 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 похожи на сдвиги (то есть деление или умножение на степень двойки) в других языках, но поскольку Go более безопасен, чем C / C ++, он выполняет дополнительную работу, когда количество сдвигов является числом ,
Инструкции сдвига в процессорах x86 учитывают только 5 бит (6 бит на 64-битных процессорах x86) счетчика сдвига. В таких языках, как C / C ++, оператор сдвига преобразуется в одну инструкцию ЦП.
Следующий код Go
x := 10
y := uint(1025) // A big shift count
println(x >> y)
println(x << y)
печать
0
0
в то время как программа C / C ++ будет печатать
5
20
<<
левый сдвиг. >>
представляет собой сдвиг вправо с расширением знака, когда левый операнд является целым числом со знаком, и сдвиг вправо с расширением нуля, когда левый операнд является целым числом без знака.
Чтобы лучше понять, >>
подумайте о
var u uint32 = 0x80000000;
var i int32 = -2;
u >> 1; // Is 0x40000000 similar to >>> in Java
i >> 1; // Is -1 similar to >> in Java
Таким образом, при применении к целому числу без знака биты слева заполняются нулем, тогда как при применении к целому числу со знаком биты слева заполняются крайним левым битом (который равен 1, когда целое число со знаком является отрицательным в соответствии с двумя дополнение).
В десятичной математике , когда мы умножаем или делим на 10 , мы производим нули в конце числа.
В двоичном , 2 имеют тот же эффект. Итак, мы добавляем ноль в конец или удаляем последнюю цифру