Integer operators
…
If the divisor is a constant, it must not be zero. If the divisor is zero at run time, a run-time panic occurs.
I’m sure you expected that. Division by zero is pretty universally not allowed.
var a = 3
var b = 0
var c = a / 0 // Won't compile
var d = a / b // run-time panic
… If the dividend is non-negative and the divisor is a constant power of 2, the division may be replaced by a right shift, and computing the remainder may be replaced by a bitwise AND operation:
x x / 4 x % 4 x >> 2 x & 3 11 2 3 2 3 -11 -2 -3 -3 1
The shift operators shift the left operand by the shift count specified by the right operand, which must be non-negative. If the shift count is negative at run time, a run-time panic occurs.
In other words…
var a = 3
var b = -1
var c = a << -1 // Won't compile
var d = a << b // run-time panic
… The shift operators implement arithmetic shifts if the left operand is a signed integer and logical shifts if it is 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 ofn
. As a result,x << 1
is the same asx*2
andx >> 1
is the same asx/2
but truncated towards negative infinity.
Let’s consider some examples of this, to make it as clear as possible:
fmt.Println(3 << 1, 3*2) // 6 6
fmt.Println(24 >> 1, 3/2) // 1 1
fmt.Println(25 >> 1, 25/2) // 12 12
fmt.Println(-25 >> 1, -25/2) // -13 -12
So as we can see, both in the description, and the example, is that shifting negative numbers right is the only time that there’s not an exact equivalent in terms of multiplication or division by 2. And that’s because right-shifting truncates toward negitive infinity (always down), whereas division truncates toward 0 (down for positive values, and up for negative).
Quotes from The Go Programming Language Specification Version of August 2, 2023