Go 语言中的整数回绕现象

为了了解整数出现回绕的原因, 我们需要将注意力放到二进制位上, 为此需要用到格式化变量 %b , 它可以以二进制位的形式打印出相应的整数值。 跟其他格式化变量一样, %b 也可以启用零填充功能并指定格式化输出的最小长度, 就像代码清单 7-3 所示的那样。

代码清单 7-3 打印二进制位: bits.go

var green uint8 = 3
fmt.Printf("%08b\n", green)    // 打印出”00000011“
green++
fmt.Printf("%08b\n", green)    // 打印出“00000100”

在代码清单 7-3 中, 对 green 的值执行加 1 操作将导致 1 进位, 而 0 则被留在原位, 最终计算得出二进制数 00000100 , 也就是十进制数 4 , 这个过程如图 7-1 所示。

图 7-1 在二进制加法中对 1 实施进位

正如代码清单 7-4 以及图 7-2 所示, 在对值为 2558 位无符号整数 blue 执行增量运算的时候, 同样的进位操作将再次出现, 但这次进位跟前一次进位有一个重要的区别: 对只有 8 位的变量 blue 来说, 最高位进位的 1 将“无处容身”, 并导致变量的值变为 0

代码清单 7-4 二进制位在整数回绕时的状态: bits-wrap.go

var blue uint8 = 255
fmt.Printf("%08b\n", blue)    // 打印出”11111111“
blue++
fmt.Printf("%08b\n", blue)    // 打印出”00000000“

图 7-2 ”无处容身“的进位

虽然回绕在某些情况下可能正好是你想要获得的状态, 但是有时候也会成为问题。 最简单的避免回绕的方法就是选用一种足够长的整数类型, 使它能够容纳你想要存储的值。

Note

本文摘录自《Go语言趣学指南》第 7 章, 请访问 gpwgcn.com 以获取更多相关信息。