Sorting a slice of floats in Go is a common requirement, whether you are working with numerical datasets or need to arrange values for reporting. Go provides a robust and efficient way to sort these collections using the built-in sort package.

Sorting Basics in Go

The standard sort package in Go offers utilities to sort slices of any type that satisfies the sort.Interface. However, for primitive data types like floats, the package provides convenient utilities.

Basic Example: Sorting a Slice of Floats

Let's start with the simplest way to sort a slice of floats using Go.

package main

import (
    "fmt"
    "sort"
)

func main() {
    // Define a slice of float64
    floats := []float64{3.14, 1.59, 2.65, 3.58, 9.79}
    
    // Sort the slice in ascending order
    sort.Float64s(floats)
    
    // Print the sorted slice
    fmt.Println(floats)
}

This code snippet demonstrates how to use sort.Float64s to sort a slice in ascending order. Remember that sort.Float64s modifies the slice in place.

Intermediate: Custom Sorting Logic

The example above sorts in ascending order. What if you need a different order, like descending? Let’s customize the sorting logic!

package main

import (
    "fmt"
    "sort"
)

// Float64Slice type extends the default slice of float64
// to implement the sort.Interface

type Float64SliceDesc []float64

func (f Float64SliceDesc) Len() int { 
    return len(f) 
}
func (f Float64SliceDesc) Swap(i, j int) { 
    f[i], f[j] = f[j], f[i] 
}
func (f Float64SliceDesc) Less(i, j int) bool { 
    return f[i] > f[j] 
}

func main() {
    floats := []float64{3.14, 1.59, 2.65, 3.58, 9.79}
    
    // Use the sort.Sort function with the custom type
    sort.Sort(Float64SliceDesc(floats))
    fmt.Println(floats) // Prints the slice in descending order
}

Here, we define a custom type Float64SliceDesc that implements the sort.Interface. The Less method is customized to sort the slice in descending order.

Advanced: Handling Universally Higher Precision

In advanced scenarios where precision is crucial, especially in a financial or scientific calculation context, slight modifications in sorting can influence outcomes.

package main

import (
    "fmt"
    "math/big"
    "sort"
)

type BigFloatSlice []*big.Float

func (b BigFloatSlice) Len() int { 
    return len(b) 
}
func (b BigFloatSlice) Swap(i, j int) {
    b[i], b[j] = b[j], b[i] 
}
func (b BigFloatSlice) Less(i, j int) bool {
    return b[i].Cmp(b[j]) == -1
}

func main() {
    a := []*big.Float{
        big.NewFloat(3.142),
        big.NewFloat(1.592),
        big.NewFloat(2.653),
        big.NewFloat(3.588),
        big.NewFloat(9.793),
    }
    
    sort.Sort(BigFloatSlice(a))

    for _, f := range a {
        fmt.Println(f)
    }
}

This advanced usage involves math/big package to handle larger precision floating-point operations. As before, we create a custom sort type BigFloatSlice that works with *big.Float to perform precision sorting.

Conclusion

Using Go’s sort package, you gain flexibility to perform both quick default sorts and fine-tune complex comparisons. Whether managing simple float64s or handling more sophisticated numerical computations, Go’s native capabilities make sorting seamless and efficient.