Go 语言中的整数回绕现象
2010 年 3 月 1 日
为了了解整数出现回绕的原因, 我们需要将注意力放到二进制位上, 为此需要用到格式化变量 %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 所示, 在对值为 255
的 8
位无符号整数 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 ”无处容身“的进位
虽然回绕在某些情况下可能正好是你想要获得的状态, 但是有时候也会成为问题。 最简单的避免回绕的方法就是选用一种足够长的整数类型, 使它能够容纳你想要存储的值。