userid := 12345
did := (userid & ^(0xFFFF << 48))
when compiling this code, I got:
./xxxx.go:511: constant -
The Go Programming Language Specification
Constants
Numeric constants represent values of arbitrary precision and do not overflow.
Constants may be typed or untyped.
A constant may be given a type explicitly by a constant declaration or conversion, or implicitly when used in a variable declaration or an assignment or as an operand in an expression. It is an error if the constant value cannot be represented as a value of the respective type.
An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required, for instance, in a short variable declaration such as i := 0 where there is no explicit type. The default type of an untyped constant is bool, rune, int, float64, complex128 or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant.
Numeric types
int
is an implementation-specific size, either 32 or 64 bits.
userid
is of type int
. For example,
package main
import "fmt"
func main() {
userid := 12345
did := uint64(userid) & ^uint64(0xFFFF<<48)
fmt.Println(userid, did)
}
Output:
12345 12345
^(0xFFFF << 48)
is an untyped constant, which in go is an arbitrarily large value.
0xffff << 48
is 0xffff000000000000
. When you negate it, you get -0xffff000000000001
(since with two's complement, -x = ^x + 1, or ^x = -(x + 1)).
When you write userid := 12345
, userid
gets the type int
. Then when you try to and (&
) it with the untyped constant -0xffff000000000001
the compiler figures that this constant needs to be an int
. At this point, the compiler complains because the value is too large in magnitude to be an int
.
If you're trying to get the constant 0x0000ffffffffffff
, then you can use 1<<48 - 1
, which (if you've got 64-bit ints), will fit. Since your code will never work if int
is 32-bits, then you should probably use int64
in your code rather than int
to make it portable.
The blog post https://blog.golang.org/constants explains how constants work, and some background on why they are the way they are.