如何在移动整数时绕过 Go int64 值限制?

How to bypass Go int64 value limits while shifting integers?

我正在尝试使用 Go 获取 KiB, MiB, ..., ZiB, Yib 的值,它们分别是 KibiByte, MebiByte, ..., ZebiByte, YobiByte.

我在 Golang 中的代码是:

package main 
import ( 
    "fmt"
)

func main() {
    s := []string{"KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}

    for k,v := range(s) {
        fmt.Printf("%s: %v\n", v, 1 << uint64(10 * (k+1)))
    }
}

但是,ZiB and YiB 的值溢出了 Go uint64,这就是我得到这个输出的原因:

KiB: 1024
MiB: 1048576
GiB: 1073741824
TiB: 1099511627776         // exceeds 1 << 32
PiB: 1125899906842624
EiB: 1152921504606846976
ZiB: 0                    // exceeds 1 << 64
YiB: 0                    // exceeds 1 << 64

否则,在这段代码中Python3中使用相同的移位逻辑:

a = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
for k,v in enumerate(a):
    print("{}: {}".format(v, 1 << (10 *(k+1))))

输出正确,如下图输出:

KiB: 1024
MiB: 1048576
GiB: 1073741824
TiB: 1099511627776
PiB: 1125899906842624
EiB: 1152921504606846976
ZiB: 1180591620717411303424
YiB: 1208925819614629174706176

那么,我怎样才能绕过 Go uint64 限制并使用移位整数获得正确的值,就像我可以使用 Python.

从移位整数中得到的一样

谢谢。

您不能使用原始 uint64 处理需要超过 64 位的数字。 Python 具有任意精度的整数,要在 Go 中获得相同的精度,您需要使用 math/big 包。

s := []string{"KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}

one := big.NewInt(1)
for k, v := range s {
    fmt.Printf("%s: %v\n", v, new(big.Int).Lsh(one, uint(10*(k+1))))
}

https://play.golang.org/p/i5v5P5QgQb