To have floating-point comparisons combine both properties of NaN being equal to itself and also approximate equality of values, filters are needed to restrict the scope of the comparison so that they are composable. This example is for demonstrative purposes; use [github.com/google/go-cmp/cmp/cmpo
()
| 121 | // This example is for demonstrative purposes; |
| 122 | // use [github.com/google/go-cmp/cmp/cmpopts.EquateApprox] instead. |
| 123 | func ExampleOption_equalNaNsAndApproximateFloats() { |
| 124 | alwaysEqual := cmp.Comparer(func(_, _ interface{}) bool { return true }) |
| 125 | |
| 126 | opts := cmp.Options{ |
| 127 | // This option declares that a float64 comparison is equal only if |
| 128 | // both inputs are NaN. |
| 129 | cmp.FilterValues(func(x, y float64) bool { |
| 130 | return math.IsNaN(x) && math.IsNaN(y) |
| 131 | }, alwaysEqual), |
| 132 | |
| 133 | // This option declares approximate equality on float64s only if |
| 134 | // both inputs are not NaN. |
| 135 | cmp.FilterValues(func(x, y float64) bool { |
| 136 | return !math.IsNaN(x) && !math.IsNaN(y) |
| 137 | }, cmp.Comparer(func(x, y float64) bool { |
| 138 | delta := math.Abs(x - y) |
| 139 | mean := math.Abs(x+y) / 2.0 |
| 140 | return delta/mean < 0.00001 |
| 141 | })), |
| 142 | } |
| 143 | |
| 144 | x := []float64{math.NaN(), 1.0, 1.1, 1.2, math.Pi} |
| 145 | y := []float64{math.NaN(), 1.0, 1.1, 1.2, 3.14159265359} // Accurate enough to Pi |
| 146 | z := []float64{math.NaN(), 1.0, 1.1, 1.2, 3.1415} // Diverges too far from Pi |
| 147 | |
| 148 | fmt.Println(cmp.Equal(x, y, opts)) |
| 149 | fmt.Println(cmp.Equal(y, z, opts)) |
| 150 | fmt.Println(cmp.Equal(z, x, opts)) |
| 151 | |
| 152 | // Output: |
| 153 | // true |
| 154 | // false |
| 155 | // false |
| 156 | } |
| 157 | |
| 158 | // Sometimes, an empty map or slice is considered equal to an allocated one |
| 159 | // of zero length. |
nothing calls this directly
no test coverage detected