Let’s start with a simple Go problem:

package main

import "fmt"

func main(a) {
        var a int8 = - 128.
        var b = a / - 1
        fmt.Println(b)
}
Copy the code

In Go, INT8 stands for a signed 8-bit integer. What do you think the output is? Before we reveal the answer at the end of this article, let’s review what signed integers are.

Signed integer

The binary representation of a number in a computer is called the machine number, and the machine number is signed. Its highest bit is the sign bit, where 0 represents a positive number and 1 represents a negative number.

In the case of an 8-bit signed integer, 0000 0001 represents 1 in decimal and 1000 0001 represents -1 in decimal.

So, you might ask, the expressible range of an 8-bit signed integer would be [1111 1111, 0111 1111], or [-127, 127], but it’s actually [-128, 127]. Where does -128 come from?

To understand the origin of -128, we also need to know the concepts of source code, inverse code, and complement.

Source, inverse, and complement

The computer needs to use a specific encoding method to store data. Source code, inverse code and complement code are all specific encoding methods. The following examples use 8-bit binary numbers.

The original code

Source code is “unmodified code”, refers to a binary number after adding a sign bit to the left of the code.

  • When the binary number is greater than 0, the sign bit is 0
  • When the binary number is less than 0, the sign bit is 1

Thus, a signed 8-bit binary number is represented in this encoding, and its value range is [1111 1111, 0111 1111], i.e. [-127, 127].

What do we get if we use the original code to compute (+1) + (-1)?

(+1) + (-1) = 0000 0001 + 1000 0001 = 1000 0010 = (-2)Copy the code

What? That equals minus 2, right? This is clearly the wrong answer.

Radix-minus-one complement

In order to solve the problem of “adding positive and negative numbers”, human beings invented inverse code.

The expression of inverse code is:

  • The inverse of a positive number is equal to its source
  • The inverse of a negative number retains the symbol bits of the original code, and then reverses the other bits

Reverse operation: change 0 to 1, and 1 to 0.

In this case, inverse code is used to calculate (+1) + (-1) :

(+1) + (-1) = 0000 0001 + 1111 1110 = 1111 1111 = (-0)Copy the code

We know that the original code of 0 is 0000 0000 or 1000 0000, and the inverse of 0 is 0000 0000 or 1111 1111. So in the inverse code, 1111, 1111, minus 0, we finally got the right answer.

complement

But the representation of the inverse code has two zeros, +0 and -0, and we want only one 0, so the complement [^3] appears.

The expression of complement is as follows:

  • The complement of a positive number is itself
  • The complement of a negative number is added to its inverse by 1

As a result of the +1 operation, a carry must occur, and if the carry exceeds the length limit, the highest bit is lost.

The highest bit loss that can occur is the inverse of -0 for 1111 1111, whose complement is 1 0000 0000. Since the length is 8 bits, the highest 1 is overflowed, so the complement of -0 is discarded and becomes 0000, 0000, which perfectly coincides with the +0 we mentioned earlier.

Use the complement to calculate (+1) + (-1) :

(+1) + (-1) = 0000 0001 + 1111 1111 = 0000 0000 = (0)Copy the code

That’s right!

Therefore, the computer uses complement to represent negative numbers internally, because it allows the same set of addition rules to be used for positive and negative numbers, so that all addition operations can be done using the same circuit.

The origin of the – 128

In order to make the finite number of digits represent as many numbers as possible, the saving of 1000, 000 is used to represent -128.

Let’s use the complement to calculate (-1) + (-127) :

(-1) + (-127) = 1000 0001 (original code) + 1111 1111 (original code) = 1111 1110 (inverse code) + 1000 0000 (inverse code) = 1111 1111 (complement) + 1000 0001 (complement code) = 1 1000 0000 (complement) = 1000 0000 (discard highest bit) = (-128)Copy the code

Minus 1 plus minus 127 is minus 128. But since 1000 0000 is the complement of -0, -128 has no corresponding source and inverse representation.

Announced the answer

Ok, let’s go back to the code at the beginning:

package main

import "fmt"

func main(a) {
        var a int8 = - 128.
        var b = a / - 1
        fmt.Println(b)
}
Copy the code

It’s obvious: int8 has a representable range of [-128, 127], so it can be assigned to -128. While (-128)/(-1) = 128 obviously exceeds this representation range, +128 as a signed integer requires 9 bits, representing 0 1000 0000. The highest bit of 0 has been overflowed, so it is discarded, resulting in 1000 0000, i.e. -128.

So the output of this code is -128

conclusion

  • int8Represents a signed 8-bit integer whose representable range is[- 128, 127]
  • The computer uses complement code internally to represent negative numbers
  • The complement is done+ 0 å’Œ 0Coexist with problems and save them0Is a minimum number -128
  • Complement enables all sets of integers to use the same set of addition rules
  • If an overflow occurs, the extra high level will be intercepted

reading

  • Talk about object-oriented programming in Go
  • Learn about arrays in Go
  • Talk about character representation and string traversal in Go

If you think the article is well written, please do me two small favors:

  1. Like and follow me to get this article seen by more people
  2. Pay attention to the public number “programming to save the world”, the public number focuses on programming foundation and server research and development, you will get the first time the new article push ~

Original is not easy, a lot of support ~ thank you!