@@ -22,6 +22,7 @@ import (
22
22
"bytes"
23
23
"fmt"
24
24
"io"
25
+ "math"
25
26
"strings"
26
27
)
27
28
@@ -46,6 +47,97 @@ func calculateRatio(matches, length int) float64 {
46
47
return 1.0
47
48
}
48
49
50
+ var (
51
+ // minNormalFloat64 is the smallest positive normal value of type float64.
52
+ minNormalFloat64 = math .Float64frombits (0x0010000000000000 )
53
+
54
+ // minNormalFloat32 is the smallest positive normal value of type float32.
55
+ minNormalFloat32 = math .Float32frombits (0x00800000 )
56
+ )
57
+
58
+ // AlmostEqualFloat64 returns true if a and b are equal within a relative error
59
+ // of epsilon. See http://floating-point-gui.de/errors/comparison/ for the
60
+ // details of the applied method.
61
+ //
62
+ // This function is copy/paste to avoid a dependency.
63
+ // https://github.com/beorn7/floats
64
+ func AlmostEqualFloat64 (a , b , epsilon float64 ) bool {
65
+ if a == b {
66
+ return true
67
+ }
68
+ absA := math .Abs (a )
69
+ absB := math .Abs (b )
70
+ diff := math .Abs (a - b )
71
+ if a == 0 || b == 0 || absA + absB < minNormalFloat64 {
72
+ return diff < epsilon * minNormalFloat64
73
+ }
74
+ return diff / math .Min (absA + absB , math .MaxFloat64 ) < epsilon
75
+ }
76
+
77
+ // AlmostEqualFloat64s is the slice form of AlmostEqualFloat64.
78
+ func AlmostEqualFloat64s (a , b []float64 , epsilon float64 ) bool {
79
+ if len (a ) != len (b ) {
80
+ return false
81
+ }
82
+ for i := range a {
83
+ if ! AlmostEqualFloat64 (a [i ], b [i ], epsilon ) {
84
+ return false
85
+ }
86
+ }
87
+ return true
88
+ }
89
+
90
+ // AlmostEqualFloat32 returns true if a and b are equal within a relative error
91
+ // of epsilon. See http://floating-point-gui.de/errors/comparison/ for the
92
+ // details of the applied method.
93
+ //
94
+ // This function is copy/paste to avoid a dependency.
95
+ // https://github.com/beorn7/floats
96
+ func AlmostEqualFloat32 (a , b , epsilon float32 ) bool {
97
+ if a == b {
98
+ return true
99
+ }
100
+ absA := AbsFloat32 (a )
101
+ absB := AbsFloat32 (b )
102
+ diff := AbsFloat32 (a - b )
103
+ if a == 0 || b == 0 || absA + absB < minNormalFloat32 {
104
+ return diff < epsilon * minNormalFloat32
105
+ }
106
+ return diff / MinFloat32 (absA + absB , math .MaxFloat32 ) < epsilon
107
+ }
108
+
109
+ // AlmostEqualFloat32s is the slice form of AlmostEqualFloat32.
110
+ func AlmostEqualFloat32s (a , b []float32 , epsilon float32 ) bool {
111
+ if len (a ) != len (b ) {
112
+ return false
113
+ }
114
+ for i := range a {
115
+ if ! AlmostEqualFloat32 (a [i ], b [i ], epsilon ) {
116
+ return false
117
+ }
118
+ }
119
+ return true
120
+ }
121
+
122
+ // AbsFloat32 works like math.Abs, but for float32.
123
+ func AbsFloat32 (x float32 ) float32 {
124
+ switch {
125
+ case x < 0 :
126
+ return - x
127
+ case x == 0 :
128
+ return 0 // return correctly abs(-0)
129
+ }
130
+ return x
131
+ }
132
+
133
+ // MinFloat32 works like math.Min, but for float32.
134
+ func MinFloat32 (x , y float32 ) float32 {
135
+ if x < y {
136
+ return x
137
+ }
138
+ return y
139
+ }
140
+
49
141
type Match struct {
50
142
A int
51
143
B int
0 commit comments