web-dev-qa-db-fra.com

Aller aux opérateurs << et >>

Quelqu'un pourrait-il m'expliquer l'utilisation de << et >> dans Go? Je suppose que c'est similaire à d'autres langues.

94
brianoh

La définition super simplifiée (peut-être trop) est simplement que << est utilisé pour "fois 2" et >> est pour "divisé par 2" - et le nombre après c'est combien de fois.

Alors n << x est "n fois 2, x fois". Et y >> z est "y divisé par 2, z fois".

Par exemple, 1 << 5 est "1 fois 2, 5 fois" ou 32. Et 32 >> 5 est "32 divisé par 2, 5 fois" ou 1.

Toutes les autres réponses donnent la définition la plus technique, mais personne ne l'a énoncée de façon très directe et j'ai pensé que vous pourriez vouloir cela.

105
Peter

D'après les spécifications de http://golang.org/doc/go_spec.html , il semble qu'au moins avec des entiers, c'est un décalage binaire. par exemple, le binaire 0b00001000 >> 1 serait 0b00000100 et 0b00001000 << 1 serait 0b00010000.


Go n'accepte apparemment pas la notation 0b pour les entiers binaires. Je l'utilisais juste pour l'exemple. En décimal, 8 >> 1 est 4 et 8 << 1 est 16. Décaler de gauche de un équivaut à multiplier par 2 et décaler de droite de un équivaut à diviser par deux, en éliminant tout reste.

87
jcomeau_ictx

Les opérateurs << et >> sont Go Arithmetic Operators .

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

Les opérateurs de décalage décalent l'opérande gauche du nombre de décalages spécifié par l'opérande droit. Ils implémentent des décalages arithmétiques si l'opérande de gauche est un entier signé et des décalages logiques s'il s'agit d'un entier non signé. Le décompte doit être un entier non signé. Il n'y a pas de limite supérieure au nombre de postes. Les décalages se comportent comme si l'opérande gauche était décalé n fois de 1 pour un décompte de n. Par conséquent, x << 1 est identique à x * 2 et x >> 1 est identique à x/2 mais tronqué vers l'infini négatif.

29
peterSO

Ils sont essentiellement opérateurs arithmétiques et c'est la même chose dans d'autres langages voici un élément de base PHP, C, Go Exemple

[~ # ~] allez [~ # ~]

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

}

Démo GO

[~ # ~] 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;
}

Démo C

[~ # ~] 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);
}

Démo PHP

Ils sortiraient tous

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 
9
Baba

Les << et >> de Go sont similaires aux changements (c'est-à-dire la division ou la multiplication par une puissance de 2) dans d'autres langues, mais comme Go est un langage plus sûr que C/C++, il fait un travail supplémentaire lorsque le nombre de changements est un nombre. .

Les instructions de décalage dans les processeurs x86 ne prennent en compte que 5 bits (6 bits sur les processeurs x86 64 bits) du nombre de décalages. Dans des langages comme C/C++, l'opérateur de décalage se traduit par une seule instruction CPU.

Le code Go suivant

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

impressions

0
0

alors qu'un programme C/C++ imprimerait

5
20
7
user811773

<< est un décalage vers la gauche. >> est un décalage vers la droite à extension de signe lorsque l'opérande gauche est un entier signé, et un décalage vers la droite à extension de zéro lorsque l'opérande gauche est un entier non signé.

Pour mieux comprendre >> penser à

var u uint32 = 0x80000000;
var i int32 = -2;

u >> 1;  // Is 0x40000000 similar to >>> in Java
i >> 1;  // Is -1 similar to >> in Java

Ainsi, lorsqu'ils sont appliqués à un entier non signé, les bits de gauche sont remplis de zéro, tandis que lorsqu'ils sont appliqués à un entier signé, les bits de gauche sont remplis avec le bit le plus à gauche (qui est 1 lorsque l'entier signé est négatif selon 2). complément).

6
Mike Samuel

En mathématiques décimales, lorsque nous multiplions ou divisons par 1, nous effectuons les zéros à la fin du nombre.

En binaire, 2 a le même effet. Nous ajoutons donc un zéro à la fin, ou supprimons le dernier chiffre

2
robert king