Fix float64 comparison test failure on archs using FMA (#1133) · prometheus/client_golang@4d54769 (original) (raw)
``
1
`+
// Copyright (c) 2015 Björn Rabenstein
`
``
2
`+
//
`
``
3
`+
// Permission is hereby granted, free of charge, to any person obtaining a copy
`
``
4
`+
// of this software and associated documentation files (the "Software"), to deal
`
``
5
`+
// in the Software without restriction, including without limitation the rights
`
``
6
`+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
`
``
7
`+
// copies of the Software, and to permit persons to whom the Software is
`
``
8
`+
// furnished to do so, subject to the following conditions:
`
``
9
`+
//
`
``
10
`+
// The above copyright notice and this permission notice shall be included in all
`
``
11
`+
// copies or substantial portions of the Software.
`
``
12
`+
//
`
``
13
`+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
`
``
14
`+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
`
``
15
`+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
`
``
16
`+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
`
``
17
`+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
`
``
18
`+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
`
``
19
`+
// SOFTWARE.
`
``
20
`+
//
`
``
21
`+
// The code in this package is copy/paste to avoid a dependency. Hence this file
`
``
22
`+
// carries the copyright of the original repo.
`
``
23
`+
// https://github.com/beorn7/floats
`
``
24
`+
package internal
`
``
25
+
``
26
`+
import (
`
``
27
`+
"math"
`
``
28
`+
)
`
``
29
+
``
30
`+
// minNormalFloat64 is the smallest positive normal value of type float64.
`
``
31
`+
var minNormalFloat64 = math.Float64frombits(0x0010000000000000)
`
``
32
+
``
33
`+
// AlmostEqualFloat64 returns true if a and b are equal within a relative error
`
``
34
`+
// of epsilon. See http://floating-point-gui.de/errors/comparison/ for the
`
``
35
`+
// details of the applied method.
`
``
36
`+
func AlmostEqualFloat64(a, b, epsilon float64) bool {
`
``
37
`+
if a == b {
`
``
38
`+
return true
`
``
39
`+
}
`
``
40
`+
absA := math.Abs(a)
`
``
41
`+
absB := math.Abs(b)
`
``
42
`+
diff := math.Abs(a - b)
`
``
43
`+
if a == 0 || b == 0 || absA+absB < minNormalFloat64 {
`
``
44
`+
return diff < epsilon*minNormalFloat64
`
``
45
`+
}
`
``
46
`+
return diff/math.Min(absA+absB, math.MaxFloat64) < epsilon
`
``
47
`+
}
`
``
48
+
``
49
`+
// AlmostEqualFloat64s is the slice form of AlmostEqualFloat64.
`
``
50
`+
func AlmostEqualFloat64s(a, b []float64, epsilon float64) bool {
`
``
51
`+
if len(a) != len(b) {
`
``
52
`+
return false
`
``
53
`+
}
`
``
54
`+
for i := range a {
`
``
55
`+
if !AlmostEqualFloat64(a[i], b[i], epsilon) {
`
``
56
`+
return false
`
``
57
`+
}
`
``
58
`+
}
`
``
59
`+
return true
`
``
60
`+
}
`