Floating Point Comparisons
Floating Point Comparisons
When you work with floating point numbers, direct equality comparisons often fail. The computer can’t represent most decimal numbers exactly in binary form. So 0.1 + 0.2 might not equal 0.3 when stored as floats.
Here’s a Go package that handles floating point comparisons properly:
import (
"fmt"
"math"
)
func main() {
// Set precision to 0.00001
var a Accuracy = func() float64 { return 0.00001 }
fmt.Println(a.Equal(0.11111222, 0.11111222233333)) // prints: true
}
type Accuracy func() float64
func (this Accuracy) Equal(a, b float64) bool {
return math.Abs(a-b) < this()
}
func (this Accuracy) Greater(a, b float64) bool {
return math.Max(a, b) == a && math.Abs(a-b) > this()
}
func (this Accuracy) Smaller(a, b float64) bool {
return math.Max(a, b) == b && math.Abs(a-b) > this()
}
func (this Accuracy) GreaterOrEqual(a, b float64) bool {
return math.Max(a, b) == a || math.Abs(a-b) < this()
}
func (this Accuracy) SmallerOrEqual(a, b float64) bool {
return math.Max(a, b) == b || math.Abs(a-b) < this()
}The key insight is simple: instead of checking if two floats are exactly equal, we check if they’re close enough. The Accuracy type holds our tolerance threshold. Two numbers are equal if their difference falls below this threshold.
This approach works well for most applications where exact floating point equality doesn’t matter. You set the precision you need, then use the comparison methods as you would with regular numbers.