Подтвердить что ты не робот

Операторы Go << и >>

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

4b9b3361

Ответ 1

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


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

Ответ 2

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

So n << x - "n раз 2, x раз". И y >> z равно "y, деленное на 2, z раз".

Например, 1 << 5 равно "1 раз 2, 5 раз" или 32. И 32 >> 5 "32 делится на 2, 5 раз" или 1.

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

Ответ 3

< < и → операторы Go Арифметические операторы.
<<   left shift             integer << unsigned integer
>>   right shift            integer >> unsigned integer

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

Ответ 4

Они в основном Арифметические операторы и то же самое на других языках здесь представляют собой базовый пример 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 

Ответ 5

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

Чтобы лучше понять >> подумайте о

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 дополнения).

Ответ 6

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

Инструкции по переключению в процессорах x86 учитывают только 5 бит (6 бит на 64-разрядных процессорах x86) из числа сдвигов. В таких языках, как C/С++, оператор сдвига преобразуется в одну инструкцию CPU.

Следующий код Go

x := 10
y := uint(1025)  // A big shift count
println(x >> y)
println(x << y)

печатает

0
0

в то время как программа C/С++ печатает

5
20

Ответ 7

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

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