uint8,int8上的算术

uint8,int8上的算术

问题描述:

What is the reason for getting negative and zero results in the Arithmetic operation on unit8 and int8 data types for the given example

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

unit8 strong>和 给定示例的 int8 strong>数据类型 p>

 包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” 
} 
  code>  pre> 
 
 

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

As shown in the other answer, and unlike some other programming languages, Go handles all integer overflow in a well-defined manner similar to what happens on most current CPUs at assembly level.


127 = 0111 1111 binary

that + 1 = 1000 0000 binary

that interpreted as signed two's complement 8 bit integer is -128.


255 = 1111 1111 binary

that + 1 = 1 0000 0000 binary (note 9 bits)

That would be 256 if we had 9 bits, but we don't, we have only 8 so it becomes 0000 0000 binary, which is 0.


Similarly for multiplication:

127*127 = 16129 = ‭0011 1111 0000 0001‬ bin

255 * 255 = 65025 = ‭1111 1110 0000 0001‬ bin

Both have lower 8 bits as 0000 0001 bin = 1


Note: most of the time, if you are relying on integer overflow, you should take a step back and think hard if this is the best way to do what you are doing. This is very low level behavior, involving exact bitwise behavior, and should always be accompanied with enough comments explaining what and why.

Go does not panic for integer overflow in runtime. As per doc:

For unsigned integer values, the operations +, -, *, and << are computed modulo 2n, where n is the bit width of the unsigned integer's type. Loosely speaking, these unsigned integer operations discard high bits upon overflow, and programs may rely on "wrap around".

For signed integers, the operations +, -, *, /, and << may legally overflow and the resulting value exists and is deterministically defined by the signed integer representation, the operation, and its operands. No exception is raised as a result of overflow. A compiler may not optimize code under the assumption that overflow does not occur. For instance, it may not assume that x < x + 1 is always true.