2016-08-08 30 views
2

我经历的go教程golang.org和我对面,我理解部分的例子来...在这个例子中这个位移是如何工作的?

MaxInt uint64  = 1<<64 - 1 

现在我明白这是移位位64米的地方这将使左它是1,然后是64 0。

我的问题是为什么这是64位数字中可以达到的最大整数。最大整数不是111111111....(until the 64th 1)而不是100000...(until the 64th one)

+1

'1 << 64 = 10000000000000000'(十六进制)'1 << 64 - 1 = FFFFFFFFFFFFFFFF'(十六进制),它是可以存储在*二进制补码*编号系统中的最大*无符号* 64位整数。 (如果你仍然坚持'1 << 64'是一个'65'位数,而不是'64') –

+1

ahh ok所以通过减去1你会使第65位消失离开'111111 .....'? – deltaskelta

+1

是的,你懂了! (但是留下'FFFF ...(十六进制数字)'或'1111 ....(64个二进制1)' –

回答

1

一步这里会发生什么情况,步:

  1. 以1

  2. 转移它到左边64位。这很棘手。结果实际上需要65位表示 - 即1个,后面跟着64个零。由于我们在这里计算一个64位的值,为什么它甚至会编译而不是溢出到0或1或产生编译错误?

  3. 它可行,因为在Go中用于计算常量的算术有点神奇(https://blog.golang.org/constants),因为它与被计算的命名常量的类型无关。你可以说foo uint8 = 1<<415/1<<414foo现在是2

  4. 减1.这使我们回到64位数,因为它实际上是11 .... 1(64倍),这实际上是最大值uint64。如果没有这一步,编译器会抱怨我们试图将65位值填入uint64

  5. 命名常量MaxInt并给它类型uint64。成功!

用于计算常量的魔术算法仍然有局限性(显然)。移位大于500左右会产生有趣的名字stupid shift错误。

相关问题