golang常量溢出uint64有什么问题
what's wrong with golang constant overflows uint64
userid := 12345
did := (userid & ^(0xFFFF << 48))
编译这段代码时,我得到:
./xxxx.go:511: constant -18446462598732840961 overflows int
你知道这是怎么回事吗?如何解决?
谢谢
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
是 int
类型。例如,
package main
import "fmt"
func main() {
userid := 12345
did := uint64(userid) & ^uint64(0xFFFF<<48)
fmt.Println(userid, did)
}
输出:
12345 12345
^(0xFFFF << 48)
是一个无类型常量,在go中是一个任意大的值。
0xffff << 48
是 0xffff000000000000
。当你否定它时,你得到 -0xffff000000000001
(因为有二进制补码,-x = ^x + 1,或 ^x = -(x + 1))。
当你写 userid := 12345
时,userid
得到类型 int
。然后,当您尝试使用无类型常量 -0xffff000000000001
和 (&
) 时,编译器认为该常量需要是 int
。此时,编译器会报错,因为该值的数量级太大,无法成为 int
.
如果您尝试获取常量 0x0000ffffffffffff
,那么您可以使用 1<<48 - 1
,它(如果您有 64 位整数)将适合。由于如果 int
是 32 位,您的代码将永远无法工作,那么您可能应该在代码中使用 int64
而不是 int
以使其可移植。
博客 post https://blog.golang.org/constants 解释了常量的工作原理,以及它们为何如此的一些背景知识。
userid := 12345
did := (userid & ^(0xFFFF << 48))
编译这段代码时,我得到:
./xxxx.go:511: constant -18446462598732840961 overflows int
你知道这是怎么回事吗?如何解决? 谢谢
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
是 int
类型。例如,
package main
import "fmt"
func main() {
userid := 12345
did := uint64(userid) & ^uint64(0xFFFF<<48)
fmt.Println(userid, did)
}
输出:
12345 12345
^(0xFFFF << 48)
是一个无类型常量,在go中是一个任意大的值。
0xffff << 48
是 0xffff000000000000
。当你否定它时,你得到 -0xffff000000000001
(因为有二进制补码,-x = ^x + 1,或 ^x = -(x + 1))。
当你写 userid := 12345
时,userid
得到类型 int
。然后,当您尝试使用无类型常量 -0xffff000000000001
和 (&
) 时,编译器认为该常量需要是 int
。此时,编译器会报错,因为该值的数量级太大,无法成为 int
.
如果您尝试获取常量 0x0000ffffffffffff
,那么您可以使用 1<<48 - 1
,它(如果您有 64 位整数)将适合。由于如果 int
是 32 位,您的代码将永远无法工作,那么您可能应该在代码中使用 int64
而不是 int
以使其可移植。
博客 post https://blog.golang.org/constants 解释了常量的工作原理,以及它们为何如此的一些背景知识。