206

Could someone please explain to me the usage of << and >> in Go? I guess it is similar to some other languages.

peterSO
  • 158,998
  • 31
  • 281
  • 276
brianoh
  • 2,079
  • 2
  • 13
  • 3

10 Answers10

358

The super (possibly over) simplified definition is just that << is used for "times 2" and >> is for "divided by 2" - and the number after it is how many times.

So n << x is "n times 2, x times". And y >> z is "y divided by 2, z times".

For example, 1 << 5 is "1 times 2, 5 times" or 32. And 32 >> 5 is "32 divided by 2, 5 times" or 1.

Amin Shojaei
  • 5,451
  • 2
  • 38
  • 46
Peter Oram
  • 6,213
  • 2
  • 27
  • 40
  • 21
    This is a great answer. This really solidified it in my head, thanks. – Sam Orozco Jan 27 '19 at 22:49
  • 14
    This is how answers should be. – Utsav Gupta May 15 '20 at 10:35
  • I'm struggling to see how this will come in handy from a novice pov – ChristoKiwi Aug 12 '21 at 23:36
  • 7
    This might have been just a tiny bit clearer if you explain that '2, x times' means '2, to the xth power'. Narratively the example sounds like you mean '5 instances of 2 added up', which would be 10 rather than 32. – schemanic Aug 25 '21 at 19:32
  • 1
    How about `3 << 0` ? – Allan Guwatudde Sep 14 '21 at 20:32
  • 1
    nice answer and Peter tried to explain it from a different view, but really, if you guys think other answers are not good, please check what 'binary' is. Peter is talking about the *exact same thing* as other answers are saying. Also, there are **arithmetic shifts** and **logical shifts**. From Go spec: *"The shift operators implement arithmetic shifts if the left operand is a signed integer and logical shifts if it is an unsigned integer."* – starriet Mar 20 '22 at 14:09
  • @AllanGuwatudde, For 3 << 0, zero time. No change on the value. Output will be 3. – K.Kirivarnan Apr 18 '22 at 08:30
  • 1
    @AllanGuwatudde according to schemanic's comment ,which should be the right answer, 3 << 0 means '3 * 2^0' the answer will be 3 because 2 to the power of 0 equals 1 – Alaa Radwan May 14 '22 at 15:15
  • @ChristoKiwi this question (https://exercism.org/tracks/go/exercises/grains) helped me understand it, you can equally check the community solutions too. – Eazy Sep 01 '22 at 22:44
136

From the spec at http://golang.org/doc/go_spec.html, it seems that at least with integers, it's a binary shift. for example, binary 0b00001000 >> 1 would be 0b00000100, and 0b00001000 << 1 would be 0b00010000.


Go apparently doesn't accept the 0b notation for binary integers. I was just using it for the example. In decimal, 8 >> 1 is 4, and 8 << 1 is 16. Shifting left by one is the same as multiplication by 2, and shifting right by one is the same as dividing by two, discarding any remainder.

peterh
  • 11,875
  • 18
  • 85
  • 108
jcomeau_ictx
  • 37,688
  • 6
  • 92
  • 107
35

The << and >> operators are Go Arithmetic Operators.

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

The shift operators shift the left operand by the shift count specified by the right operand. They implement arithmetic shifts if the left operand is a signed integer and logical shifts if it is an unsigned integer. The shift count must be an unsigned integer. There is no upper limit on the shift count. Shifts behave as if the left operand is shifted n times by 1 for a shift count of n. As a result, x << 1 is the same as x*2 and x >> 1 is the same as x/2 but truncated towards negative infinity.

peterSO
  • 158,998
  • 31
  • 281
  • 276
22

They are basically Arithmetic operators and its the same in other languages here is a basic PHP , C , Go Example

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

They would all output

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 
Baba
  • 94,024
  • 28
  • 166
  • 217
13

n << x = n * 2^x   Example: 3 << 5 = 3 * 2^5 = 96

y >> z = y / 2^z   Example: 512 >> 4 = 512 / 2^4 = 32

spatial
  • 131
  • 1
  • 2
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 22 '22 at 02:32
8

<< is left shift. >> is sign-extending right shift when the left operand is a signed integer, and is zero-extending right shift when the left operand is an unsigned integer.

To better understand >> think of

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

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

So when applied to an unsigned integer, the bits at the left are filled with zero, whereas when applied to a signed integer, the bits at the left are filled with the leftmost bit (which is 1 when the signed integer is negative as per 2's complement).

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
8

Go's << and >> are similar to shifts (that is: division or multiplication by a power of 2) in other languages, but because Go is a safer language than C/C++ it does some extra work when the shift count is a number.

Shift instructions in x86 CPUs consider only 5 bits (6 bits on 64-bit x86 CPUs) of the shift count. In languages like C/C++, the shift operator translates into a single CPU instruction.

The following Go code

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

prints

0
0

while a C/C++ program would print

5
20
  • 4
    For C and C++ shift operators, "The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand." The C and C++ standards do not guarantee that C and C++ programs will print 5 and 20. – peterSO Dec 22 '11 at 03:18
  • @peterSO: Yes, you are right. My standpoint is that each programming language standard has to have a concrete implementation on a concrete CPU. In the context of a single CPU family (x86-32), the behavior of all C/C++ compilers is (can be expected to be) the same. The reason for this is that emitting exactly 1 SHL/SHR/etc instruction to implement the shift operator is the best thing that an optimizing C/C++ compiler can do when the context does not tell it anything about 'x' and 'y'. And, if the compiler knows for a fact that the code has undefined behavior, it should inform the user about it. –  Dec 22 '11 at 09:10
  • 2
    I disagree. You should write portable code. Both Linux and Windows run on ARM. Focusing on a single CPU family is short-sighted. Also, y is a variable. For a fact, the compiler has no knowledge of its actual runtime values. – peterSO Dec 22 '11 at 15:45
  • @Atom Apart from the language providing absolutely no guarantees about what will happen, undefined behavior is likely to vary even on a single machine with a single compiler, if for example you change compilation options (eg an optimised build). Relying on it _in any way_ is dangerously wrong IMO. – Paul Hankin May 17 '12 at 14:04
  • @Anonymous Yes, but that is only theory. Can you provide a concrete example where changing compilation options leads to different behavior of `<<` or `>>` in C/C++? –  May 20 '12 at 14:38
7

In decimal math, when we multiply or divide by 10, we effect the zeros on the end of the number.

In binary, 2 has the same effect. So we are adding a zero to the end, or removing the last digit

Rusty Rob
  • 16,489
  • 8
  • 100
  • 116
1

<< is the bitwise left shift operator ,which shifts the bits of corresponding integer to the left….the rightmost bit being ‘0’ after the shift .

For example:

In gcc we have 4 bytes integer which means 32 bits .

like binary representation of 3 is

00000000 00000000 00000000 00000011

3<<1 would give

00000000 00000000 00000000 00000110 which is 6.

In general 1<<x would give you 2^x

In gcc

1<<20 would give 2^20 that is 1048576

but in tcc it would give you 0 as result because integer is of 2 bytes in tcc.

in simple terms we can take it like this in golang So

n << x is "n times 2, x times". And y >> z is "y divided by 2, z times".

n << x = n * 2^x Example: 3<< 5 = 3 * 2^5 = 96

y >> z = y / 2^z Example: 512 >> 4 = 512 / 2^4 = 32

Tawseef Bhat
  • 370
  • 4
  • 12
0

These are Right bitwise and left bitwise operators

dılo sürücü
  • 3,821
  • 1
  • 26
  • 28