Go > Core Go Basics > Fundamental Data Types > Complex numbers (complex64, complex128)

Working with Complex Numbers in Go

This example demonstrates how to declare, initialize, and perform basic arithmetic operations using complex numbers in Go (complex64 and complex128). It covers creating complex numbers from real and imaginary parts, extracting these parts, and performing addition, subtraction, multiplication, and division.

Declaring and Initializing Complex Numbers

This code snippet shows how to declare complex numbers using the `complex64` and `complex128` types. `complex64` uses 32 bits each for the real and imaginary parts (total 64 bits), while `complex128` uses 64 bits for each (total 128 bits). The `complex()` function is used to create a complex number from its real and imaginary parts. Go also allows shorthand initialization using the `i` suffix for the imaginary component; if you use shorthand, the type will default to `complex128`.

package main

import (
	"fmt"
)

func main() {
	// Declare a complex64 variable
	var c1 complex64 = complex(5, -2) // Real part: 5, Imaginary part: -2

	// Declare a complex128 variable
	var c2 complex128 = complex(8.2, 3.5) // Real part: 8.2, Imaginary part: 3.5

	fmt.Println("Complex64:", c1)
	fmt.Println("Complex128:", c2)

	// Initialize using shorthand notation
	c3 := 3 + 4i  // complex128 by default
	fmt.Println("Complex128 (shorthand):	", c3)
}

Extracting Real and Imaginary Parts

The `real()` and `imag()` functions are used to extract the real and imaginary parts of a complex number, respectively. These functions return float64 values, regardless of whether the original complex number was `complex64` or `complex128`. This is because these functions have signatures that returns float64.

package main

import (
	"fmt"
)

func main() {
	c := complex128(3 + 4i)

	// Extract the real and imaginary parts
	realPart := real(c)
	imaginaryPart := imag(c)

	fmt.Println("Complex Number:", c)
	fmt.Println("Real Part:", realPart)
	fmt.Println("Imaginary Part:", imaginaryPart)
}

Basic Arithmetic Operations

Go supports standard arithmetic operations (+, -, *, /) with complex numbers. The operations are performed element-wise on the real and imaginary components, following standard complex number arithmetic rules. The result of these operations will be a complex number.

package main

import (
	"fmt"
)

func main() {
	c1 := complex128(5 + 2i)
	c2 := complex128(2 - 3i)

	// Addition
	sum := c1 + c2
	fmt.Println("Sum:", sum)

	// Subtraction
	difference := c1 - c2
	fmt.Println("Difference:", difference)

	// Multiplication
	product := c1 * c2
	fmt.Println("Product:", product)

	// Division
	quotient := c1 / c2
	fmt.Println("Quotient:", quotient)
}

Concepts Behind Complex Numbers

Complex numbers extend the real number system by including an imaginary unit, denoted as `i`, where `i² = -1`. A complex number is typically written in the form `a + bi`, where `a` is the real part and `b` is the imaginary part. Complex numbers are used in various fields like electrical engineering, quantum mechanics, and signal processing.

Real-Life Use Case

In electrical engineering, complex numbers are used to represent alternating current (AC) circuits. The impedance of a circuit, which includes resistance, capacitance, and inductance, can be represented as a complex number. This allows engineers to easily analyze and design AC circuits.

Best Practices

  • Choose the appropriate complex type (`complex64` or `complex128`) based on the required precision and memory constraints. `complex128` provides more precision but requires more memory.
  • Use the `complex()` function for creating complex numbers from real and imaginary parts.
  • Use the `real()` and `imag()` functions for extracting the real and imaginary parts.
  • Go provides robust support for performing calculations with complex numbers with ease.

Interview Tip

Be prepared to explain the difference between `complex64` and `complex128`, how to create complex numbers, and how to perform basic arithmetic operations with them. Understanding their real-world applications, such as in electrical engineering, can also be beneficial.

When to Use Them

Complex numbers are useful when dealing with problems that involve oscillations, wave phenomena, or any situation where a two-dimensional representation is needed. Consider using them when real numbers alone are insufficient to model the problem domain.

Memory Footprint

`complex64` consumes 8 bytes of memory (4 bytes for the real part and 4 bytes for the imaginary part). `complex128` consumes 16 bytes of memory (8 bytes for the real part and 8 bytes for the imaginary part). Consider the memory implications when dealing with a large number of complex numbers.

Alternatives

While Go has native support for complex numbers, you *could* technically represent complex numbers using structs with float fields for real and imaginary parts and manually implement the operations. However, this is generally not recommended due to the performance and readability advantages of the built-in complex types. Libraries implementing matrix operations and other numerical computations may also provide their own complex number implementations tailored to specific optimizations, but these are usually special cases.

Pros

  • Native support in Go, making them efficient and easy to use.
  • Provide a convenient way to represent and manipulate two-dimensional data.
  • Built-in functions (`complex()`, `real()`, `imag()`) simplify working with complex numbers.

Cons

  • `complex128` can consume a significant amount of memory if used extensively.
  • Can be less intuitive than real numbers for developers unfamiliar with complex number theory.

FAQ

  • What is the difference between complex64 and complex128?

    complex64 uses 32 bits for both the real and imaginary parts, while complex128 uses 64 bits for both. Therefore, complex128 provides higher precision than complex64 but also consumes more memory.
  • How do I create a complex number in Go?

    You can create a complex number using the complex() function, passing the real and imaginary parts as arguments. Alternatively, you can use shorthand notation, such as 3 + 4i, which will default to `complex128`.
  • How can I get the real and imaginary parts of a complex number?

    Use the real() and imag() functions to extract the real and imaginary parts of a complex number. These functions return float64 values.