V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
nevermoreluo
V2EX  ›  Go 编程语言

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

  •  
  •   nevermoreluo · 117 天前 · 2287 次点击
    这是一个创建于 117 天前的主题,其中的信息可能已经有所发展或是发生改变。

    初学 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))
    
    }
    
    第 1 条附言  ·  117 天前

    可能是我的问题提问的方式不对,我有疑问的原因是,理所当然的认为const没有声明go又是强类型应该和cpp的auto一样,在编译时推断Big的类型,在运行时处理。所以才会问这个Big在运行时的类型问题。

    不过anyway,可以结帖了。

    TLDR;
    go在编译时直接处理了值,如果这些untyped value需要运行时执行并且无法满足默认类型时会报错。

    所以go可以在编译时这些值可以被精确的计算出Small的值, 但是运行时打印Big会被当成int从而overflow报错。

    楼里提到的相关资料:
    https://stackoverflow.com/questions/38982278/how-does-go-perform-arithmetic-on-constants/38982889#38982889

    https://go.dev/blog/constants

    https://www.ardanlabs.com/blog/2014/04/introduction-to-numeric-constants-in-go.html

    但是这样又开始了一个迷思,为什么他可以处理这些数,go对于这个精确的值处理范围有极限嘛? 可能有空了要再去探索下。

    16 条回复    2024-07-24 00:36:01 +08:00
    uiosun
        1
    uiosun  
       117 天前
    dapang1221
        2
    dapang1221  
       117 天前
    鉴定为计算机原理没学好,重新看下书
    nevermoreluo
        3
    nevermoreluo  
    OP
       117 天前
    @uiosun
    这篇我看了 但是还是没搞明白这个 Big 到底属于什么类型。
    或者说我的问题应该改为
    对于 go 来说他既然可以运算 Small 的值,那么在运行时他拿什么类型处理 Big 这个超出他规定基础类型的对象的?
    pkoukk
        4
    pkoukk  
       117 天前
    你没声明它的类型它哪来的类型?
    aminobody
        5
    aminobody  
       117 天前
    @nevermoreluo #3 `The default type for the untyped constant Big is int.`
    nevermoreluo
        6
    nevermoreluo  
    OP
       117 天前
    @aminobody 1 << 100 超出 int 的存储范围了
    nevermoreluo
        7
    nevermoreluo  
    OP
       117 天前
    看到这个
    https://stackoverflow.com/questions/38982278/how-does-go-perform-arithmetic-on-constants/38982889#38982889

    大概理解了,在编译时把这个值处理了,运行时就不用考虑了,所以企图打印他会在编译时报错,但是计算可以。
    谢谢各位大佬
    otakustay
        8
    otakustay  
       117 天前
    超出范围就溢出呗,溢出又不会改变类型
    zonyitoo
        9
    zonyitoo  
       117 天前   ❤️ 2
    nevermoreluo
        10
    nevermoreluo  
    OP
       117 天前
    @zonyitoo
    因为没有声明类型,先入为主的以为跟 c++的 auto 一样编译时推断了。
    看起来这个 const 在 go 里面有很多细节处理,学习了,谢谢大佬。
    lasuar
        11
    lasuar  
       117 天前
    默认一律是 int 类型,数据溢出按溢出处理,搜索 [编程语言整型溢出] ,
    nevermoreluo
        12
    nevermoreluo  
    OP
       117 天前
    @lasuar
    应该不是的,他并没有做溢出处理,而是在编译时精确的计算了。
    你可以简单打印以下这几个值看看。如果按他最大基础类型 uint64 算的话,溢出处理,和实际结果不对。

    const Big = 18446744073709551617;
    const OtherBig = Big + 1;
    const BigI = OtherBig - 3;
    lasuar
        13
    lasuar  
       117 天前
    这里因为是常量方式的声明,所以直接编译失败了。类型默认 INT ,没有如果。
    wudanyang
        14
    wudanyang  
       117 天前
    编译的时候就出错了,还有啥类型
    uiosun
        15
    uiosun  
       117 天前
    @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)
    wisej
        16
    wisej  
       116 天前   ❤️ 1
    来回答你 append 里的问题:

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

    这些答案可以在 src/go/constant/value.go 源码找到
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3047 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 13:48 · PVG 21:48 · LAX 05:48 · JFK 08:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.