Skip to content

Commit 4691831

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 4691831

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

prometheus/histogram_test.go

+25-6
Original file line numberDiff line numberDiff line change
@@ -355,13 +355,12 @@ func TestBuckets(t *testing.T) {
355355

356356
got = ExponentialBucketsRange(1, 100, 10)
357357
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,
358+
1.0, 1.6681, 2.7825, 4.6415, 7.7426, 12.9154, 21.5443,
359+
35.9381, 59.9484, 100.0000,
362360
}
363-
if !reflect.DeepEqual(got, want) {
364-
t.Errorf("exponential buckets range: got %v, want %v", got, want)
361+
const tolerance = 0.0001
362+
if !equalFloat64s(got, want, 0.0001) {
363+
t.Errorf("exponential buckets range: got %v, want %v (tolerance %f)", got, want, tolerance)
365364
}
366365
}
367366

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

0 commit comments

Comments
 (0)