userid := 12345
did := (userid & ^(0xFFFF << 48))
when compiling this code, I got:
./xxxx.go:511: constant -18446462598732840961 overflows int
Do you know what is the matter with this and how to solve it ? Thanks.
^(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.
The Go Programming Language Specification
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.
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