Skip to content

Commit e8353d9

Browse files
committed
Fix float64 comparison test failure on archs using FMA
Architectures using FMA optimization yield slightly different results so we cannot assume floating point values will be precisely the same across different architectures. The solution in this change is to check "abs(a-b) < tolerance" instead of comparing the exact values. This will give us confidence that the histogram buckets are near identical. Signed-off-by: Seth Bunce <[email protected]>
1 parent 9801a4e commit e8353d9

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

prometheus/histogram_test.go

+25-7
Original file line numberDiff line numberDiff line change
@@ -354,14 +354,12 @@ func TestBuckets(t *testing.T) {
354354
}
355355

356356
got = ExponentialBucketsRange(1, 100, 10)
357-
want = []float64{
358-
1.0, 1.6681005372000588, 2.782559402207125,
359-
4.641588833612779, 7.742636826811273, 12.915496650148842,
360-
21.544346900318846, 35.93813663804629, 59.94842503189414,
361-
100.00000000000007,
357+
want = []float64{1.0, 1.6681, 2.7825, 4.6415, 7.7426, 12.9154, 21.5443,
358+
35.9381, 59.9484, 100.0000,
362359
}
363-
if !reflect.DeepEqual(got, want) {
364-
t.Errorf("exponential buckets range: got %v, want %v", got, want)
360+
const tolerance = 0.0001
361+
if !equalFloat64s(got, want, 0.0001) {
362+
t.Errorf("exponential buckets range: got %v, want %v (tolerance %f)", got, want, tolerance)
365363
}
366364
}
367365

@@ -467,3 +465,23 @@ func TestHistogramExemplar(t *testing.T) {
467465
}
468466
}
469467
}
468+
469+
// equalFloat64 returns true if a and b are within the tolerance. We have this
470+
// because float comparison varies on different architectures. For example,
471+
// architectures which do FMA yield slightly different results.
472+
// https://github.com/prometheus/client_golang/pull/899#issuecomment-1244506390
473+
func equalFloat64(a, b, tolerance float64) bool {
474+
return math.Abs(a-b) < tolerance
475+
}
476+
477+
func equalFloat64s(a, b []float64, tolerance float64) bool {
478+
if len(a) != len(b) {
479+
return false
480+
}
481+
for i := range a {
482+
if !equalFloat64(a[i], b[i], tolerance) {
483+
return false
484+
}
485+
}
486+
return true
487+
}

0 commit comments

Comments
 (0)