golang常量溢出uint64有什么问题

时间:2015-04-22 03:51:54

标签: go integer-overflow

userid := 12345
did := (userid & ^(0xFFFF << 48))

编译此代码时,我得到了:

  

./xxxx.go:511: constant -18446462598732840961 overflows int

你知道这件事有什么关系吗?如何解决? 感谢。

2 个答案:

答案 0 :(得分:10)

^(0xFFFF << 48)是一个无类型的常量,它的值是任意大的值。

0xffff << 480xffff000000000000。当你否定它时,你得到-0xffff000000000001(因为有两个补码,-x = ^ x + 1,或^ x = - (x + 1))。

当您撰写userid := 12345时,userid会获得int类型。然后,当您尝试使用无类型常量&并且(-0xffff000000000001)时,编译器会发现此常量需要为int。此时,编译器会抱怨,因为该值太大而不能为int

如果你想要获得常量0x0000ffffffffffff,那么你可以使用1<<48 - 1,它(如果你有64位整数)将适合。由于如果int为32位,您的代码将无法运行,那么您应该在代码中使用int64而不是int来使其可移植。

博客文章https://blog.golang.org/constants解释了常量的工作原理,以及有关它们原因的一些背景知识。

答案 1 :(得分:2)

  

The Go Programming Language Specification

     

Constants

     

数字常量表示任意精度的值,而不是   溢出。

     

常量可以是键入的或无类型的。

     

常量可以通过常量声明明确地给出一个类型   转换,或在变量声明或。中使用时隐式转换   赋值或作为表达式中的操作数。如果这是一个错误   常数值不能表示为各自的值   类型。

     

非类型化常量具有默认类型,该类型是   在类型值为的上下文中隐式转换常量   例如,在一个简短的变量声明中,例如i:= 0   没有明确类型的地方。无类型的默认类型   常量是bool,rune,int,float64,complex128或string   分别取决于它是否是布尔值,符文,整数,   浮点,复数或字符串常量。

     

Numeric types

     

int是特定于实现的大小,32位或64位。

userid的类型为int。例如,

package main

import "fmt"

func main() {
    userid := 12345
    did := uint64(userid) & ^uint64(0xFFFF<<48)
    fmt.Println(userid, did)
}

输出:

12345 12345