初学 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))

}
最新回复 (15)
  • uiosun4月前
    引用2
  • dapang12214月前
    引用3
    鉴定为计算机原理没学好,重新看下书
  • nevermoreluo楼主4月前
    引用4
    @uiosun
    这篇我看了 但是还是没搞明白这个 Big 到底属于什么类型。
    或者说我的问题应该改为
    对于 go 来说他既然可以运算 Small 的值,那么在运行时他拿什么类型处理 Big 这个超出他规定基础类型的对象的?
  • pkoukk4月前
    引用5
    你没声明它的类型它哪来的类型?
  • aminobody4月前
    引用6
    @nevermoreluo #3 `The default type for the untyped constant Big is int.`
  • nevermoreluo楼主4月前
    引用7
    @aminobody 1 << 100 超出 int 的存储范围了
  • nevermoreluo楼主4月前
    引用8
    看到这个
    https://stackoverflow.com/questions/38982278/how-does-go-perform-arithmetic-on-constants/38982889

    大概理解了,在编译时把这个值处理了,运行时就不用考虑了,所以企图打印他会在编译时报错,但是计算可以。
    谢谢各位大佬
  • otakustay4月前
    引用9
    超出范围就溢出呗,溢出又不会改变类型
  • zonyitoo4月前
    引用10
    https://www.ardanlabs.com/blog/2014/04/introduction-to-numeric-constants-in-go.html

    因为你的 Big 并没有指定类型,所以它是 kind: integer 。

    https://go.dev/ref/spec
  • nevermoreluo楼主4月前
    引用11
    @zonyitoo
    因为没有声明类型,先入为主的以为跟 c++的 auto 一样编译时推断了。
    看起来这个 const 在 go 里面有很多细节处理,学习了,谢谢大佬。
  • lasuar4月前
    引用12
    默认一律是 int 类型,数据溢出按溢出处理,搜索 [编程语言整型溢出] ,
  • nevermoreluo楼主4月前
    引用13
    @lasuar
    应该不是的,他并没有做溢出处理,而是在编译时精确的计算了。
    你可以简单打印以下这几个值看看。如果按他最大基础类型 uint64 算的话,溢出处理,和实际结果不对。

    const Big = 18446744073709551617;
    const OtherBig = Big + 1;
    const BigI = OtherBig - 3;
  • lasuar4月前
    引用14
    这里因为是常量方式的声明,所以直接编译失败了。类型默认 INT ,没有如果。
  • wudanyang4月前
    引用15
    编译的时候就出错了,还有啥类型
  • uiosun4月前
    引用16
    @nevermoreluo

    这篇问答里的 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)
  • 回复请 登录 or 快速注册
返回