Перейти << и >> операторы - PullRequest
       12

Перейти << и >> операторы

93 голосов
/ 27 апреля 2011

Может ли кто-нибудь объяснить мне использование << и >> в Go?Я думаю, что это похоже на некоторые другие языки.

Ответы [ 7 ]

104 голосов
/ 21 апреля 2014

Супер (возможно, сверх) упрощенное определение состоит в том, что << используется для «времен 2», а >> для «делится на 2», а число после него - сколько раз.

То есть n << x - это «n раз 2, x раза». И y >> z - это "у, деленное на 2, z раз".

Например, 1 << 5 - это «1 раз 2, 5 раз» или 32. И 32 >> 5 - это «32, деленное в 2,5 раза» или 1.

Все остальные ответы дают более техническое определение, но никто не высказал это прямо, и я подумал, что вы можете этого захотеть.

87 голосов
/ 27 апреля 2011

Из спецификации в http://golang.org/doc/go_spec.html, кажется, что, по крайней мере, с целыми числами, это двоичный сдвиг.например, двоичный 0b00001000 >> 1 будет 0b00000100, а 0b00001000 << 1 будет 0b00010000. </p>


Go, очевидно, не принимает нотацию 0b для двоичных целых чисел.Я просто использовал это для примера.В десятичном формате 8 >> 1 равно 4, а 8 << 1 равно 16. Сдвиг влево на единицу - это то же самое, что и умножение на 2, а смещение вправо на единицу - это то же самое, что и деление на два, отбрасывая любой остаток.

29 голосов
/ 27 апреля 2011

Операторами << и >> являются Арифметические операторы Go .

<<   left shift             integer << unsigned integer
>>   right shift            integer >> unsigned integer

Операторы сдвига смещают левый операнд на число сдвига, указанное правым операндом.Они реализуют арифметические сдвиги, если левый операнд представляет собой целое число со знаком, и логические сдвиги, если это целое число без знака.Счетчик сдвига должен быть целым числом без знака.Там нет верхнего предела на счет смены.Сдвиги ведут себя так, как будто левый операнд смещен n раз на 1 для числа сдвигов n.В результате x << 1 совпадает с x * 2, а x >> 1 совпадает с x / 2, но усекается до отрицательной бесконечности.

9 голосов
/ 02 августа 2013

В основном это Арифметические операторы , и то же самое на других языках. Вот базовый пример PHP, C, Go

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)
    }

}

GO Demo

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;
}

C Demo

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);
}

PHP Demo

Все они будут выводить

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 
7 голосов
/ 22 декабря 2011

<< и >> в Go аналогичны сменам (то есть делению или умножению на степень 2) в других языках, но поскольку Go является более безопасным языком, чем C / C ++, он выполняет дополнительную работу при подсчете смен это число.

В инструкциях по смене в процессорах x86 учитывается только 5 бит (6 бит в 64-битных процессорах x86) от числа смен. В таких языках, как 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
6 голосов
/ 06 июля 2011

<< - сдвиг влево.>> - расширяющий знак правый сдвиг, когда левый операнд представляет собой целое число со знаком, и расширяющий ноль правый сдвиг, когда левый операнд представляет собой целое число без знака.*

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, когдацелое число со знаком является отрицательным согласно дополнению 2).

2 голосов
/ 15 февраля 2017

В десятичная математика , когда мы умножаем или делим на 10 , мы влияем на нули в конце числа.

В двоичный файл , 2 имеет тот же эффект. Поэтому мы добавляем ноль в конец или удаляем последнюю цифру

...