【问题标题】:Arithmetic on uint8, int8uint8、int8 上的算术运算
【发布时间】:2019-02-09 11:11:01
【问题描述】:

在给定示例的 unit8int8 数据类型上的算术运算中得到负数和零结果的原因是什么

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"
}

https://play.golang.org/p/_a2KHP29t5p

【问题讨论】:

  • 您可以提出问题,那么您希望得到什么结果?
  • @hyde 我正在学习 Golang,据我了解,这些导致数据类型值溢出是我所知道的。
  • 一般情况下,127 = 01111111b; that+1 = 10000000b = -128 当解释为有符号二进制补码整数时。但是语言的类型转换规则也很重要,所以不要为 Go 写答案。
  • 和 255 = 11111111b; that+1 = 100000000b 9 位,无符号 8 位整数只适合 00000000b = 0,这基本上是所有现代 CPU 和语言处理无符号溢出的方式。
  • @hyde 谢谢,现在了解加法是如何工作的。

标签: go int


【解决方案1】:

Go 在运行时不会因为整数溢出而恐慌。根据doc

对于无符号整数值,操作 +、-、* 和

对于有符号整数,操作 +、-、*、/ 和

【讨论】:

  • 哈,我不禁觉得文本是对 C 和 C++ 如何处理问题的微妙挖掘!
  • 我也是这么想的。 Go 本身就是对 C 的一种微妙挖掘?
【解决方案2】:

如另一个答案所示,与其他一些编程语言不同,Go 以明确定义的方式处理所有整数溢出,类似于大多数当前 CPU 在汇编级别上发生的情况。


127 = 0111 1111 二进制

that + 1 = 1000 0000 二进制

解释为带符号二进制补码的 8 位整数是 -128。


255 = 1111 1111 二进制

that + 1 = 1 0000 0000 二进制(注意 9 位)

如果我们有 9 位,那将是 256,但我们没有,我们只有 8,所以它变成 0000 0000 二进制,即 0。


乘法也一样:

127*127 = 16129 = 0011 1111 0000 0001 仓

255 * 255 = 65025 = 1111 1110 0000 0001 仓

两者的低 8 位为 0000 0001 bin = 1


注意:大多数情况下,如果您依赖整数溢出,您应该退后一步,认真思考一下,这是否是您正在做的事情的最佳方式。这是非常低级的行为,涉及精确的按位行为,并且应该始终伴随着足够多的 cmets 来解释是什么以及为什么。

【讨论】:

  • 乘法呢?
  • 来自另一个答案的引用:"对于无符号整数值,操作 +、-、* 和 这基本上意味着,只需删除不适合该类型的位。
  • 用乘法更新
猜你喜欢
  • 1970-01-01
  • 2018-05-26
  • 2019-03-04
  • 2020-10-07
  • 2016-06-16
  • 2016-03-10
  • 1970-01-01
  • 2018-10-16
  • 1970-01-01
相关资源
最近更新 更多