对于给定示例,在 unit8 和 int8 数据类型上进行算术运算的结果为负且为零的原因是什么
package main
import (
"fmt"
)
func main() {
var u uint8 = 255
fmt.Println(u, u+1, u*u) // "255 0 1"
var i int8 = 127
fmt.Println(i, i+1, i*i) // "127 -128 1"
}
答案 0 :(得分:4)
Go在运行时不会因整数溢出而惊慌。根据{{3}}:
对于无符号整数值,运算符+,-,*和<<为 计算模2n,其中n是无符号整数的位宽度 类型。松散地说,这些无符号整数运算会丢弃高位 一旦溢出,程序就可能依赖于“环绕”。
对于有符号整数,可以合法地使用+,-,*,/和<<操作 溢出,结果值存在并且确定 由带符号的整数表示形式,操作及其定义 操作数。溢出不会引发异常。编译器 在溢出不会导致错误的假设下可能无法优化代码 发生。例如,可能不会假设x
答案 1 :(得分:2)
如其他答案所示,与某些其他编程语言不同,Go以一种定义明确的方式处理所有整数溢出,类似于在汇编级别上当前大多数CPU上发生的情况。
127 = 0111 1111二进制
那个+ 1 = 1000 0000二进制
被解释为带符号的二进制补码8位整数是-128。
255 = 1111 1111二进制
那个+1 = 1 0000 0000二进制(注9位)
如果我们有9位,那将是256,但我们没有,只有8位,所以它变成了0000 0000二进制,即0。
类似地用于乘法:
127 * 127 = 16129 =00111111 00000001bin
255 * 255 = 65025 =11111110 00000001bin
两者的低8位均为0000 0001 bin = 1
注意:在大多数情况下,如果您依赖整数溢出,则应该退后一步,认真思考这是否是完成工作的最佳方法。这是一种非常低级的行为,涉及确切的按位行为,并且应始终附有足够的注释来解释什么和原因。