what's wrong with golang constant overflows uint64

只愿长相守 提交于 2019-12-29 08:10:10

问题


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.


回答1:


^(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.




回答2:


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


来源:https://stackoverflow.com/questions/29787422/whats-wrong-with-golang-constant-overflows-uint64

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!