各位大佬,在 Golang Go语言中一个 const 声明超出 uint64 最大值后这个数的类型是什么?

发布于 1周前 作者 gougou168 来自 Go语言

初学 go ,看教程 const的时候,发现 Big = 1 << 100 明显超出基础类型 uint64 了,于是想看下 Big 是什么类型

但是打印都 overflow 了遂有此疑问


const (
    // 将 1 左移 100 位来创建一个非常大的数字
    // 即这个数的二进制是 1 后面跟着 100 个 0
    Big = 1 << 100
    // 再往右移 99 位,即 Small = 1 << 1 ,或者说 Small = 2
    Small = Big >> 99
)

func main() { // cannot use Big (untyped int constant 1267650600228229401496703205376) as int value in argument to fmt.Printf (overflows) fmt.Printf(“T of Big %T\n”, Big) // cannot use Big (untyped int constant 1267650600228229401496703205376) as int value in argument to reflect.TypeOf (overflows) fmt.Println("T of Big ", reflect.TypeOf(Big))

}


各位大佬,在 Golang Go语言中一个 const 声明超出 uint64 最大值后这个数的类型是什么?

更多关于各位大佬,在 Golang Go语言中一个 const 声明超出 uint64 最大值后这个数的类型是什么?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

17 回复

更多关于各位大佬,在 Golang Go语言中一个 const 声明超出 uint64 最大值后这个数的类型是什么?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


鉴定为计算机原理没学好,重新看下书


这篇我看了 但是还是没搞明白这个 Big 到底属于什么类型。
或者说我的问题应该改为
对于 go 来说他既然可以运算 Small 的值,那么在运行时他拿什么类型处理 Big 这个超出他规定基础类型的对象的?

你没声明它的类型它哪来的类型?

#3 The default type for the untyped constant Big is int.

1 << 100 超出 int 的存储范围了

看到这个
https://stackoverflow.com/questions/38982278/how-does-go-perform-arithmetic-on-constants/38982889#38982889

大概理解了,在编译时把这个值处理了,运行时就不用考虑了,所以企图打印他会在编译时报错,但是计算可以。
谢谢各位大佬

超出范围就溢出呗,溢出又不会改变类型


因为没有声明类型,先入为主的以为跟 c++的 auto 一样编译时推断了。
看起来这个 const 在 go 里面有很多细节处理,学习了,谢谢大佬。

默认一律是 int 类型,数据溢出按溢出处理,搜索 [编程语言整型溢出] ,


应该不是的,他并没有做溢出处理,而是在编译时精确的计算了。
你可以简单打印以下这几个值看看。如果按他最大基础类型 uint64 算的话,溢出处理,和实际结果不对。

const Big = 18446744073709551617;
const OtherBig = Big + 1;
const BigI = OtherBig - 3;

这里因为是常量方式的声明,所以直接编译失败了。类型默认 INT ,没有如果。

编译的时候就出错了,还有啥类型



这篇问答里的 comment 有更多文章可以阅读,其中以官方文档为例:

> But in Go, a constant is just a simple, unchanging value, and from here on we’re talking only about Go.

按我理解,常量只是作为一个值,当你需要推断它的类型时,Go 才会尝试推断它的类型——推断。

所以,你的报错很正常,正是反映了这样的规则:cannot use Big (untyped int constant 1267650600228229401496703205376) as int value in argument to fmt.Printf (overflows)

来回答你 append 里的问题:

1. Big 常量,底层用的 math/big 包
2. precision 有极限,golang 自带的 compiler 设的 512bit (不过根据 spec ,integer constants 不小于 256 即可)。1<<511 没问题, 1<<512 就报 overflow 了

这些答案可以在 src/go/constant/value.go 源码找到

在 Golang(Go 语言)中,const 声明用于定义常量,而常量的类型是根据其值以及上下文自动推断的。当你声明一个常量并且其值超出了 uint64 的最大值(即 18446744073709551615),Go 会将其类型推断为未指定大小的整数类型,这种类型在 Go 中被称为“untyped constant”(无类型常量)。

无类型常量具有特殊的性质,它们不绑定于具体的整型大小(如 int, uint, int64 等),而是可以根据上下文进行类型转换。这意味着,当这个无类型常量被用于需要特定类型整数的表达式中时,Go 编译器会自动将其转换为所需类型的整数,只要这种转换不会导致值的丢失或溢出。

例如,如果你将这个超过 uint64 最大值的常量赋值给一个 float64 类型的变量,Go 会将其转换为 float64 类型。如果赋值给一个 big.Int 类型(来自 Go 的 math/big 包),则会转换为高精度的整数类型。

总结来说,在 Go 语言中,当一个 const 声明的值超出 uint64 最大值时,这个数会被视为无类型常量,其类型会在后续使用中根据上下文自动推断和转换。这种设计提供了极大的灵活性和便利性,允许开发者编写更通用和安全的代码。

回到顶部