这个位移位在这个例子中是如何工作的?
How is this bitshifting working in this example?
我正在阅读 golang.org 上的 go
教程,我遇到了一个我部分理解的示例...
MaxInt uint64 = 1<<64 - 1
现在我明白这是将位向左移动 64 位,这将使它成为 1 后跟 64 个 0。
我的问题是为什么这是 64 位数字可以达到的最大整数。最大整数不是 111111111....(until the 64th 1)
而不是 100000...(until the 64th one)
吗?
这里发生了什么,一步一步:
取1.
左移64位。这很棘手。结果实际上需要 65 位来表示——即 1 后跟 64 个零。既然我们在这里计算一个 64 位值,为什么这甚至可以编译而不是溢出到 0 或 1 或产生编译错误?
之所以有效,是因为 Go 中用于计算常量的算法有点神奇 (https://blog.golang.org/constants),因为它与正在计算的命名常量的类型无关。你可以说 foo uint8 = 1<<415 / 1<<414
并且 foo
现在是 2
.
减1。这让我们回到64位数字,因为它实际上是11....1(64次),这确实是uint64
的最大值。如果没有这一步,编译器会抱怨我们试图将 65 位值塞入 uint64
.
将常量命名为 MaxInt
并为其指定类型 uint64
。成功!
用于计算常量的魔法算法仍然有局限性(很明显)。大于 500 次左右的偏移会产生有趣的命名 stupid shift
错误。
我正在阅读 golang.org 上的 go
教程,我遇到了一个我部分理解的示例...
MaxInt uint64 = 1<<64 - 1
现在我明白这是将位向左移动 64 位,这将使它成为 1 后跟 64 个 0。
我的问题是为什么这是 64 位数字可以达到的最大整数。最大整数不是 111111111....(until the 64th 1)
而不是 100000...(until the 64th one)
吗?
这里发生了什么,一步一步:
取1.
左移64位。这很棘手。结果实际上需要 65 位来表示——即 1 后跟 64 个零。既然我们在这里计算一个 64 位值,为什么这甚至可以编译而不是溢出到 0 或 1 或产生编译错误?
之所以有效,是因为 Go 中用于计算常量的算法有点神奇 (https://blog.golang.org/constants),因为它与正在计算的命名常量的类型无关。你可以说
foo uint8 = 1<<415 / 1<<414
并且foo
现在是2
.减1。这让我们回到64位数字,因为它实际上是11....1(64次),这确实是
uint64
的最大值。如果没有这一步,编译器会抱怨我们试图将 65 位值塞入uint64
.将常量命名为
MaxInt
并为其指定类型uint64
。成功!
用于计算常量的魔法算法仍然有局限性(很明显)。大于 500 次左右的偏移会产生有趣的命名 stupid shift
错误。