Go: Integer type

Elucian MoiseElucian Moise
6 min read

In Go, the integer data type is used to represent whole numbers without fraction or decimal components. There are several built-in types to represent integers of different sizes:

  • int8: Represents signed 8-bit integers with a range between -128 to 127.

  • int16: Represents signed 16-bit integers with a range between -32,768 to 32,767.

  • int32: Represents signed 32-bit integers with a range between -2,147,483,648 to 2,147,483,647.

  • int64: Represents signed 64-bit integers with a range between -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

  • uint8: Represents unsigned 8-bit integers with a range between 0 to 255.

  • uint16: Represents unsigned 16-bit integers with a range between 0 to 65,535.

  • uint32: Represents unsigned 32-bit integers with a range between 0 to 4,294,967,295.

  • uint64: Represents unsigned 64-bit integers with a range between 0 to 18,446,744,073,709,551,615.

Here's a table that shows the integer data types along with their size in bytes and range of values:

Data TypeSize (bytes)Minimum ValueMaximum Value
int81-128127
int162-32,76832,767
int324-2,147,483,6482,147,483,647
int648-9,223,372,036,854,775,8089,223,372,036,854,775,807
uint810255
uint162065,535
uint32404,294,967,295
uint648018,446,744,073,709,551,615

Integer expressions

Here are some examples of expressions with all the arithmetic operators using the int data type:

package main

import "fmt"

func main() {
   // Initializing variables
   var num1 int = 32
   var num2 int = 16

   // Addition
   fmt.Println(num1 + num2) // Output: 48

   // Subtraction
   fmt.Println(num1 - num2) // Output: 16

   // Multiplication
   fmt.Println(num1 * num2) // Output: 512

   // Division
   fmt.Println(num1 / num2) // Output: 2

   // Modulus
   fmt.Println(num1 % num2) // Output: 0

   // Increment
   num1++
   fmt.Println(num1) // Output: 33

   // Decrement
   num2--
   fmt.Println(num2) // Output: 15
}

In this example, I have created two int variables named num1 and num2. I have used arithmetic operators like addition (+), subtraction (-), multiplication (*), division (/), and modulus (%) to perform arithmetic operations with these variables. Additionally, I've also used increment (++) and decrement (--) operators with these variables for demonstration purposes.


Operator priority

Operator priority, also known as operator precedence, refers to the order in which operations are carried out in an expression. It helps determine which operation is executed first when there are multiple operations in an expression.

In Go, the operator priority follows the same rules as most other programming languages such as C. Here is a list of the highest to lowest priority for some common operators in Go:

  1. Unary operators (++--, !, -)

  2. Multiplicative operators (*, /, %)

  3. Additive operators (+, -)

  4. Comparison operators (==, !=, <, <=, >, >=)

  5. Logical operators (&&, ||)

Example:

Here's an example of how operator priority can affect the result of an expression in Go:

a, b, c, d := 10, 5, 2, 1

result := a - b * (c + d)

fmt.Println(result)

// Output: 0

In this example, the multiplication operator has higher priority than the subtraction operator. So the expression b * (c + d) is evaluated first, resulting in b * (2 + 1) or 5 * 3 which is equal to 15. Then the subtraction operation is carried out resulting in 10 - 15 or -5.

However, if we use parentheses to change the order of evaluation, the expression will have a different result:

result := (a - b) * (c + d)

fmt.Println(result)

// Output: 30

In this example, the subtraction operation is carried out first because it has higher priority than the multiplication operator within the parentheses. Then the multiplication operation is carried out.


Signed vs Unsigned

The main differences between signed and unsigned integers are as follows:

  1. Range of values: Signed integers can represent both negative and positive values, while unsigned integers can only represent non-negative values.

  2. Memory utilization: Unsigned integers do not need to reserve a sign bit, which makes them slightly more memory-efficient than their signed counterparts.

  3. Arithmetic operations: Arithmetic operations with signed integers are more complex than with unsigned integers because sign extension must be taken into account.

The similarities between signed and unsigned integers are:

  1. Both signed and unsigned integers are primitive data types used to represent whole numbers.

  2. They are used in various programming languages to perform arithmetic operations, comparisons, and bit manipulations.

  3. Both types of integers can be stored in integer variables and arrays.

  4. In many programming languages, the size of both signed and unsigned integers is fixed (for example, 32 bits or 64 bits).

It is important to choose the appropriate type of integer according to the specific requirements of the program. If negative or positive values may be represented, a signed integer is appropriate. If only non-negative values are required or if memory efficiency is a concern, then an unsigned integer may be a better choice.

Example:

Here are examples of signed and unsigned integers in Go:

package main

import (
    "fmt"
)

func main() {
    // signed integer
    var a int = -10
    fmt.Println(a)

    // unsigned integer
    var b uint = 20
    fmt.Println(b)

    // multiplication of signed and unsigned integers
    var c int = a * int(b)
    fmt.Println(c)

    // overflow of signed integer
    var d int8 = 127
    d = d + 1
    fmt.Println(d) // will print -128 due to integer overflow

    // overflow of unsigned integer
    var e uint8 = 255
    e = e + 1
    fmt.Println(e) // will print 0 due to integer overflow
}

In the above code, we first declare a signed integer a and an unsigned integer b. We then perform multiplication of a and b, which is allowed in Go because both types can be converted to a larger, signed integer.

Next, we demonstrate the risk of integer overflow by declaring a signed integer d with a maximum value of 127 (in 8 bits). We then add 1 to d, causing the value to overflow and wrap around to -128. Similarly, we declare an unsigned integer e with a maximum value of 255 (in 8 bits), and add 1 to it to cause an overflow, resulting in the value 0.

This example illustrates how different types of integers can have different ranges of values and limitations, and how integer overflow can cause unexpected behavior in code.


Conclusion:

Knowing the integer data type is very important. This type is fast and precise but it can't represent decimal numbers. If you like this article buy me a cofee. If you find no value in it or find errors blame ChatGPT and comment below.


Learn and prosper ๐Ÿ€๐Ÿ––๐Ÿผ

0
Subscribe to my newsletter

Read articles from Elucian Moise directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Elucian Moise
Elucian Moise

Software engineer instructor, software developer and community leader. Computer enthusiast and experienced programmer. Born in Romania, living in US.