Part 1: Understanding Basic Data Types in Go - Integers, Floats, and Booleans explained

Go is a statically typed language, meaning that the type of a variable is set at compile time, which helps catch many errors early in development. We’ll cover three essential data types in Go: integers, floats, and booleans. Mastering these basic data types is crucial because they’re used frequently in virtually every Go program.


Integers in Go

Integers are whole numbers, positive or negative, without any fractional part. Go provides a variety of integer types to handle different ranges of values, making it a powerful tool for memory management and performance tuning.

  • Types of Integers

    1. Signed Integers:

      • Go’s signed integers can store both positive and negative values

      • Types: int, int8, int16, int32, int64.

      • The number in each type represents the bit size:

        • int8: Stores integers from -128 to 127

        • int16: Stores integers from -32,768 to 32,767

        • int32: Stores integers from -2,147,483,648 to 2,147,483,647

        • int64: Stores integers from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

    2. Unsigned Integers:

      • Unsigned integers only store non-negative values, making them useful when you know the variable will never hold a negative number.

      • Types: uint, uint8 (alias for byte), uint16, uint32, uint64

      • Ranges:

        • uint8: 0 to 255

        • uint16: 0 to 65,535

        • uint32: 0 to 4,294,967,295

        • uint64: 0 to 18,446,744,073,709,551,615

    3. Default Integer Type:

      • int and uint are the default integer types in Go.

      • The size of int and uint depends on the underlying platform: 32 bits on 32-bit systems and 64 bits on 64-bit systems. Generally, using int for general-purpose variables is more efficient than specifying bit sizes.

  • Declaring and Using Integers

      package main
    
      import "fmt"
    
      func main() {
          var a int = 10 // declaring and assigning an int variable
          var b int8 = -128 // declaring and assigning an int8 variable
          var c uint16 = 500 // declaring and assigning a uint16 variable
    
          fmt.Println("a:", a)
          fmt.Println("b:", b)
          fmt.Println("c:", c)
      }
    

    Output

      a: 10
      b: -128
      c: 500
    

Integer Operations
Integers support various arithmetic operations:

  • Addition (+): Adds two or more integers.

  • Subtraction (-): Subtracts one integer from another.

  • Multiplication (*): Multiplies integers.

  • Division (/): Divides one integer by another.

  • Modulus (%): Finds the remainder of a division.

      package main
    
      import "fmt"
    
      func main() {
          x := 10
          y := 3
    
          fmt.Println("Addition:", x + y) 
          fmt.Println("Subtraction:", x - y)
          fmt.Println("Multiplication:", x * y) 
          fmt.Println("Division:", x / y)
          fmt.Println("Modulus:", x % y)
      }
    
  • Output:

      Addition: 13
      Subtraction: 7
      Multiplication: 30
      Division: 3
      Modulus: 1
    

Floating Point Numbers (Floats) in Go

Floats are used to store numbers with a fractional part, that is, numbers that require a decimal point.

  • Types of Floats

    1. float32: Single-precision floating-point numbers with a precision of about 6-7 decimal places.

    2. float64: Double-precision floating-point numbers with a precision of about 15-16 decimal places. This is the default type for floats and is generally recommended for calculations that require precision.

  • Declaring and Using Floats

      package main
    
      import "fmt"
    
      func main() {
          var pi float64 = 3.14159 // Declaring a float64 variable
          var e float32 = 2.718    // Declaring a float32 variable
    
          fmt.Println("pi:", pi)
          fmt.Println("e:", e)
      }
    

    Output:

      pi: 3.14159
      e: 2.718
    
  • Floating-Point Operations
    Floating-point numbers support the same arithmetic operations as integers, but they also allow the division to produce a floating-point result.

      package main
    
      import "fmt"
    
      func main() {
          a := 5.2
          b := 2.0
    
          fmt.Println("Addition:", a + b)
          fmt.Println("Subtraction:", a - b)
          fmt.Println("Multiplication:", a * b)
          fmt.Println("Division:", a / b)
      }
    

    Output

      Addition: 7.2
      Subtraction: 3.2
      Multiplication: 10.4
      Division: 2.6
    
  • Precision and Rounding Errors

    In Go, floating-point arithmetic can sometimes lead to imprecise results due to how decimal numbers are represented in binary. For calculations that require high precision or to avoid rounding errors, you can use the math package for rounding or the math/big for arbitrary-precision arithmetic.

    • Using math package for rounding:

      The math package provides functions like math.Round, math.Floor, and math.Ceil to handle rounding of floating-point numbers.

      • math.Round: It is used to round a floating-point number to the nearest integer. It is defined as func Round(x float64) float64 in the math package.

          package main
        
          import (
              "fmt"
              "math"
          )
        
          func main() {
              num1 := 3.5
              rounded1 := math.Round(num1)
              fmt.Println("rounded1:", rounded1)
        
              num2 := 2.3
              rounded2 := math.Round(num2)
              fmt.Println("rounded2:", rounded2)
        
              num3 := -2.5
              rounded3 := math.Round(num3)
              fmt.Println("rounded3:", rounded3)
        
              num4 := 5.0
              rounded4 := math.Round(num4)
              fmt.Println("rounded4:", rounded4)
          }
        

        Output:

          rounded1: 4
          rounded2: 2
          rounded3: -3
          rounded4: 5
        
      • math.Floor: It is used to return the largest integer value that is less than or equal to a given number. It is defined as func Floor(x float64) float64 in the math package. Rounds down a floating-point number.

          package main
        
          import (
              "fmt"
              "math"
          )
        
          func main() {
              num1 := 3.14
              floor1 := math.Floor(num1)
              fmt.Println("floor1:", floor1)
        
              num2 := -2.71
              floor2 := math.Floor(num2)
              fmt.Println("floor2:", floor2)
        
              num3 := 5.0
              floor3 := math.Floor(num3)
              fmt.Println("floor3:", floor3)
          }
        

        Output:

          floor1: 3
          floor2: -3
          floor3: 5
        
      • math.Ceil: It is used to return the smallest integer value greater than or equal to the specified number. Basically, It is used to round up decimal numbers. It is defined as func Ceil(x float64) float64 in the math package. Basically, rounds up decimal numbers.

          package main
        
          import (
              "fmt"
              "math"
          )
        
          func main() {
              num1 := 3.14
              ceiling1 := math.Ceil(num1)
              fmt.Println("ceiling1:", ceiling1)
        
              num2 := -2.71
              ceiling2 := math.Ceil(num2)
              fmt.Println("ceiling2:", ceiling2)
        
              num3 := 5.0
              ceiling3 := math.Ceil(num)
              fmt.Println("ceiling3:", ceiling3)
          }
        

        Output:

          ceiling1: 4
          ceiling2: -2
          ceiling3: 5
        
    • Using math/big Package for arbitrary-precision arithmetic:

      If your calculations are very precision-sensitive, you can use the math/big package, which provides arbitrary-precision arithmetic with the big.Float Type. This is particularly useful for applications like financial calculations where exact decimal representation is necessary.

        package main
      
        import (
            "fmt"
            "math/big"
        )
      
        func main() {
            // Create new big.Float values
            f1 := big.NewFloat(1.234567890123456789)
            f2 := big.NewFloat(9.876543210987654321)
      
            // Addition
            sum := new(big.Float).Add(f1, f2)
            fmt.Println("Sum of Floats:", sum.String())
      
            // Multiplication
            prod := new(big.Float).Mul(f1, f2)
            fmt.Println("Product of Floats:", prod.String())
        }
      

      Output:

        Sum of Floats: 11.1111111
        Product of Floats: 12.19326311
      
    • When to use these different approaches:

      • Use the math package for simple rounding when small rounding errors are acceptable, and you don’t need very high precision.

      • Use the math/big Package when you need high precision in your calculations, such as in financial or scientific applications where exact values are crucial.


Booleans in Go

Booleans are used to represent truth values in Go. It is represented as bool.

  • The boolean type:

    1. true

    2. false

The default boolean type is false.

  • Declaring and Using Booleans

    Booleans are often used in control structures to drive conditional logic in programs. Conditional logic executes different actions in a program based on whether certain conditions are met. It enables a program to make decisions, such as "if this condition is true, then perform this action."

      package main
    
      import "fmt"
    
      func main() {
          var isGoAwesome bool = true // Declaring a boolean variable
    
          fmt.Println("Is Go awesome?", isGoAwesome) // Output: true
      }
    

    Output:

      Is Go awesome? true
    
  • Boolean Operations

    Boolean values support logical operations, which are essential for flow control and decision-making in Go programs:

    • Logical AND (&&): Returns true only if both operands are true. If either operand is false, the result is false.

    • Logical OR (||): Returns true if at least one of the operands is true. It only returns false when both operands are false.

    • Logical NOT (!): Reverses the value of a boolean operand. If the operand is true, it returns false; if it is false, it returns true.

        package main
      
        import "fmt"
      
        func main() {
            a := true
            b := false
      
            fmt.Println("a AND b:", a && b)
            fmt.Println("a OR b:", a || b)
            fmt.Println("NOT a:", !a)
        }
      

      Output:

        a AND b: false
        a OR b: true
        NOT a: false
      
  • Conditional statements with Booleans

    Booleans are often used in conditional statements to control the flow of a program.

      package main
    
      import "fmt"
    
      func main() {
          isRaining := false
          temperature := 20
    
          if isRaining {
              fmt.Println("Take an umbrella.")
          } else {
              fmt.Println("No need for an umbrella.")
          }
    
          if temperature > 25 {
              fmt.Println("It's hot outside.")
          } else {
              fmt.Println("It's cool outside.")
          }
      }
    

    Output:

      No need for an umbrella.
      It's cool outside.
    

    In this example, the boolean isRaining and the condition on temperature help guide the program’s output based on different conditions.


Integers, floats, and booleans form the backbone of Go’s data types, allowing you to perform calculations, control program flow, and handle data efficiently. Understanding these types is crucial for any Go developer because they appear in virtually every program, from the simplest to the most complex applications.

In the next part of this series, we’ll dive into strings, another fundamental data type in Go, which is used to work with textual data. We’ll cover everything from basic operations to handling UTF-8 encoded characters in strings, providing a solid understanding of how Go manages and manipulates text. Happy coding!