public double overlapPercentWith(StatisticRange other)
    {
        requireNonNull(other, "other is null");

        if (this.isEmpty() || other.isEmpty() || this.distinctValues == 0 || other.distinctValues == 0) {
            return 0.0; // zero is better than NaN as it will behave properly for calculating row count
        }

        if (this.equals(other)) {
            return 1.0;
        }

        double lengthOfIntersect = min(this.high, other.high) - max(this.low, other.low);
        if (isInfinite(lengthOfIntersect)) {
            if (isFinite(this.distinctValues) && isFinite(other.distinctValues)) {
                return min(other.distinctValues / this.distinctValues, 1);
            }
            return INFINITE_TO_INFINITE_RANGE_INTERSECT_OVERLAP_HEURISTIC_FACTOR;
        }
        if (lengthOfIntersect == 0) {
            return 1 / max(this.distinctValues, 1);
        }
        if (lengthOfIntersect < 0) {
            return 0;
        }
        if (isInfinite(length()) && isFinite(lengthOfIntersect)) {
            return INFINITE_TO_FINITE_RANGE_INTERSECT_OVERLAP_HEURISTIC_FACTOR;
        }
        if (lengthOfIntersect > 0) {
            return lengthOfIntersect / length();
        }

        return NaN;
    }
@Test
    public void testOverlapPercentWith()
    {
        StatisticRange zeroToTen = range(0, 10, 10);
        StatisticRange empty = StatisticRange.empty();

        // Equal ranges
        assertOverlap(zeroToTen, range(0, 10, 5), 1);
        assertOverlap(zeroToTen, range(0, 10, 20), 1);
        assertOverlap(zeroToTen, range(0, 10, 20), 1);

        // Some overlap
        assertOverlap(zeroToTen, range(5, 3000, 3), 0.5);

        // Single value overlap
        assertOverlap(zeroToTen, range(3, 3, 1), 1 / zeroToTen.getDistinctValuesCount());
        assertOverlap(zeroToTen, range(10, 100, 357), 1 / zeroToTen.getDistinctValuesCount());

        // No overlap
        assertOverlap(zeroToTen, range(20, 30, 10), 0);

        // Empty ranges
        assertOverlap(zeroToTen, empty, 0);
        assertOverlap(empty, zeroToTen, 0);
        // no test for empty, empty) since any return value is correct
        assertOverlap(unboundedRange(10), empty, 0);

        // Unbounded (infinite), NDV-based
        assertOverlap(unboundedRange(10), unboundedRange(20), 1);
        assertOverlap(unboundedRange(20), unboundedRange(10), 0.5);

        assertOverlap(unboundedRange(0.1), unboundedRange(1), 1);
        assertOverlap(unboundedRange(0.0), unboundedRange(1), 0);
        assertOverlap(unboundedRange(0.0), unboundedRange(0), 0);
    }