diff --git a/libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialScaleUtils.java b/libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialScaleUtils.java index a9a93cf023369..a27fbeea89093 100644 --- a/libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialScaleUtils.java +++ b/libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialScaleUtils.java @@ -234,9 +234,19 @@ static double exponentiallyScaledToDoubleValue(long index, int scale) { */ public static double getPointOfLeastRelativeError(long bucketIndex, int scale) { checkIndexAndScaleBounds(bucketIndex, scale); - double upperBound = getUpperBucketBoundary(bucketIndex, scale); double histogramBase = Math.pow(2, Math.scalb(1, -scale)); - return 2 / (histogramBase + 1) * upperBound; + if (Double.isFinite(histogramBase)) { + double upperBound = getUpperBucketBoundary(bucketIndex, scale); + return 2 / (histogramBase + 1) * upperBound; + } else { + if (bucketIndex >= 0) { + // the bucket is (1, +inf), approximate point of least error as inf + return Double.POSITIVE_INFINITY; + } else { + // the bucket is (1/(Inf), 1), approximate point of least error as 0 + return 0; + } + } } /** diff --git a/libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/ExponentialScaleUtilsTests.java b/libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/ExponentialScaleUtilsTests.java index a75aedbf35231..68371395a4df2 100644 --- a/libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/ExponentialScaleUtilsTests.java +++ b/libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/ExponentialScaleUtilsTests.java @@ -79,6 +79,12 @@ public void testExtremeValueIndexing() { } } + public void testPointOfLeastErrorAtInfinity() { + assertThat(getPointOfLeastRelativeError(0, MIN_SCALE), equalTo(Double.POSITIVE_INFINITY)); + assertThat(getPointOfLeastRelativeError(-1, MIN_SCALE), equalTo(0.0)); + assertThat(getPointOfLeastRelativeError(10, MIN_SCALE + 2), equalTo(Double.POSITIVE_INFINITY)); + } + public void testRandomValueIndexing() { for (int i = 0; i < 100_000; i++) { // generate values in the range 10^-100 to 10^100