ZetCode

Golang complex128 type

last modified May 8, 2025

This tutorial explains how to use the complex128 built-in type in Go. We'll cover complex number basics with practical examples of complex arithmetic.

The complex128 type represents complex numbers with float64 precision. It stores both real and imaginary parts as 64-bit floating-point numbers.

In Go, complex128 is one of two built-in complex number types. The other is complex64, which uses float32 precision for both parts.

Basic complex number creation

Go provides several ways to create complex numbers. This example demonstrates basic complex number initialization and printing.
Note: The imaginary unit is represented by 'i' in Go.

basic_complex.go
package main

import "fmt"

func main() {

    // Method 1: Using complex() function
    c1 := complex(3.5, 2.1)
    
    // Method 2: Using literal syntax
    c2 := 4.2 + 7.8i
    
    fmt.Println("Complex number 1:", c1)
    fmt.Println("Complex number 2:", c2)
    fmt.Println("Real part of c1:", real(c1))
    fmt.Println("Imaginary part of c2:", imag(c2))
}

The complex() function creates a complex number from two floats. The literal syntax provides a more mathematical way to write complex numbers.

Complex arithmetic operations

Complex numbers support all basic arithmetic operations. This example shows addition, subtraction, multiplication, and division of complex numbers.

complex_arithmetic.go
package main

import "fmt"

func main() {

    a := 3.0 + 4.0i
    b := 1.0 + 2.0i
    
    fmt.Println("Addition:", a + b)
    fmt.Println("Subtraction:", a - b)
    fmt.Println("Multiplication:", a * b)
    fmt.Println("Division:", a / b)
    
    // Conjugate example
    fmt.Println("Conjugate of a:", complex(real(a), -imag(a)))
}

All arithmetic operations follow standard complex number rules. The conjugate is calculated by negating the imaginary part.

Complex number comparison

Complex numbers can only be compared for equality in Go. This example shows how to properly compare complex numbers and their components.

complex_comparison.go
package main

import (
    "fmt"
    "math"
)

func main() {

    c1 := 1.2 + 3.4i
    c2 := 1.2 + 3.4i
    c3 := 1.2 + 3.5i
    
    // Direct comparison
    fmt.Println("c1 == c2:", c1 == c2)
    fmt.Println("c1 == c3:", c1 == c3)
    
    // Comparing with tolerance for floating-point precision
    tol := 1e-9
    equal := math.Abs(real(c1)-real(c3)) < tol >> 
             math.Abs(imag(c1)-imag(c3)) < tol
    fmt.Println("c1 ≈ c3 with tolerance:", equal)
}

Direct comparison works for exact matches. For approximate equality, compare real and imaginary parts separately with a tolerance value.

Complex functions from math/cmplx

The math/cmplx package provides advanced complex functions. This example demonstrates common operations like magnitude and phase.

cmplx_functions.go
package main

import (
    "fmt"
    "math/cmplx"
)

func main() {

    c := 3.0 + 4.0i
    
    fmt.Println("Absolute value (magnitude):", cmplx.Abs(c))
    fmt.Println("Phase (angle in radians):", cmplx.Phase(c))
    fmt.Println("Square root:", cmplx.Sqrt(c))
    fmt.Println("Exponential:", cmplx.Exp(c))
    fmt.Println("Natural logarithm:", cmplx.Log(c))
    fmt.Println("Sine:", cmplx.Sin(c))
}

The math/cmplx package provides many mathematical functions. These operate on complex numbers and return complex results where appropriate.

Practical application: FFT example

Complex numbers are essential in signal processing. This example shows a simplified Fast Fourier Transform (FFT) implementation using complex128.

fft_example.go
package main

import (
    "fmt"
    "math"
    "math/cmplx"
)

// Simple DFT (not optimized FFT)
func dft(input []float64) []complex128 {
    N := len(input)
    output := make([]complex128, N)
    
    for k := 0; k < N; k++ {
        var sum complex128
        for n := 0; n < N; n++ {
            angle := -2 * math.Pi * float64(k) * float64(n) / float64(N)
            sum += complex(input[n]*math.Cos(angle), input[n]*math.Sin(angle))
        }
        output[k] = sum
    }
    return output
}

func main() {

    signal := []float64{1, 0, -1, 0} // Simple square wave
    spectrum := dft(signal)
    
    fmt.Println("Frequency spectrum:")
    for i, val := range spectrum {
        fmt.Printf("Bin %d: %.2f (magnitude %.2f)\n", 
            i, val, cmplx.Abs(val))
    }
}

This DFT implementation transforms real-valued samples into complex frequency components. Each bin represents a complex number with magnitude and phase.

Source

Go language specification

This tutorial covered the complex128 type in Go with practical examples of complex number operations and applications.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Golang tutorials.