Integers
Integers can be broadly divided into two categories: unsigned integers and signed integers. Signed integers are the most widely used.
Unsigned means that it can only represent non-negative numbers (0 and positive numbers), while signed numbers can represent both negative and non-negative numbers.
Unsigned integers can be divided into four sizes: 8 bits, 16 bits, 32 bits, and 64 bits, represented by uint8
, uint16
, uint32
, and uint64
, respectively. The corresponding signed integers are int8
, int16
, int32
, and int64
. The following table shows the different ranges represented by each type:
Type |
Description |
Range |
uint8 |
8-bit unsigned int |
0 to 255 |
int8 |
8-bit signed int |
-128 to 127 |
uint16 |
16-bit unsigned int |
0 to 65535 |
int16 |
16-bit signed int |
-32768 to 32767 |
uint32 |
32-bit unsigned int |
0 to 4294967295 |
int32 |
32-bit signed int |
-2147483648 to 2147483647 |
uint64 |
64-bit unsigned int |
0 to 18446744073709551615 |
int64 |
64-bit signed int |
-9223372036854775808 to 9223372036854775807 |
Let's take uint8
and int8
as examples. They are both 8-bit integers and can represent 256 values. In the unsigned integer type uint8
, the range it can represent is from 0 to 255, while in the signed integer type int8
, the range it can represent is from -128 to 127.
In addition to the above 8 types, there are three other special integer types, uint
, int
, and uintptr
, where uint
and int
may represent different ranges on different platforms, and uintptr
is used for storing pointer addresses.
Type |
Range |
uint |
uint32 on 32-bit systems, uint64 on 64-bit systems |
int |
int32 on 32-bit systems, int64 on 64-bit systems |
uintptr |
Unsigned integer type used for storing pointer addresses, mostly used in low-level programming like unsafe operations |
Now, let's create a file named integer.go
to demonstrate the use of integers:
cd ~/project
touch integer.go
package main
import (
"fmt"
"unsafe"
)
func main() {
// View the type of int in the current environment
// Declare a as the type int
var a int
// Use unsafe.Sizeof() to output the memory size occupied by the type
fmt.Printf("The type int in the current environment is %d bits\n", unsafe.Sizeof(a)*8)
var b int8 = 125
// Use the %d placeholder in fmt.Printf to output the value of the integer
// Use the %T placeholder in fmt.Printf to output the type of the variable
fmt.Printf("The value of b is %d, and the type is %T\n", b, b)
// Integer operations
// Declare integers c and d, and calculate their sum
c, d := 2, 3
fmt.Printf("c + d = %d\n", c+d)
// 10 - 5
fmt.Printf("10 - 5 = %d\n", 10-5)
// 8 * 10
fmt.Printf("8 * 10 = %d\n", 8*10)
// Example of uintptr usage - storing an address
var ptr uintptr
x := 42
// Convert the pointer to x to uintptr
ptr = uintptr(unsafe.Pointer(&x))
fmt.Printf("The address of x stored in ptr is: %v\n", ptr)
}
After executing the program, we get the following output:
go run integer.go
The type int in the current environment is 64 bits
The value of b is 125, and the type is int8
c + d = 5
10 - 5 = 5
8 * 10 = 80
The address of x stored in ptr is: 824634818784
Explanation of the output:
The type int in the current environment is 64 bits
: This line shows that the int
type on the system where the code is being run is 64 bits (or 8 bytes), indicating it is an int64
. The unsafe.Sizeof(a)
returns the size of variable a
in bytes, and multiplying by 8 converts it to bits. This means that the int
type can hold larger integer values.
The value of b is 125, and the type is int8
: Here, we have declared a variable b
of type int8
and assigned it the value 125. The output confirms this by showing both the value and the data type.
c + d = 5
, 10 - 5 = 5
, 8 * 10 = 80
: These lines showcase basic integer arithmetic operations: addition, subtraction, and multiplication. The output confirms the correct results of these calculations.
The address of x stored in ptr is: 824634818784
: This demonstrates how uintptr
can be used to store a memory address. We're converting a pointer to the integer variable x
to a uintptr
type. The actual address value will vary each time the program runs. This is an advanced use case typically found in unsafe operations and system programming.
In this file, the unsafe.Sizeof()
function can be used to obtain the number of bytes occupied by the current variable type. 1 byte (byte) is equal to 8 bits, so unsafe.Sizeof()*8
can obtain the number of bits occupied by the type. From the output, we can see that the online environment is 64 bits. The actual type of int
in the online environment is int64
.
We can use the following command in the terminal to determine the current system architecture:
dpkg --print-architecture
amd64