package geniusweb.bidspace; import java.math.BigDecimal; import java.math.RoundingMode; /** * An interval [min, max]. * */ public class Interval { public static Interval ZERO = new Interval(BigDecimal.ZERO, BigDecimal.ZERO); private final BigDecimal min; private final BigDecimal max; /** * AN interval [min,max]. If min > max, then there are no values in this * interval. * * @param min the minimum value of the interval (inclusive) * @param max the maximum value of the interval (inclusive) */ public Interval(BigDecimal min, BigDecimal max) { if (min == null || max == null) { throw new NullPointerException("min and max must contain not null"); } this.min = min; this.max = max; } /** * * @return the minimum value of the interval */ public BigDecimal getMin() { return min; } /** * * @return the maximum value of the interval */ public BigDecimal getMax() { return max; } /** * * @return true iff this range does not contain any element. */ public boolean isEmpty() { return min.compareTo(max) > 0; } /** * * @param value the value to test * @return true iff min ≤ value ≤ max */ public boolean contains(BigDecimal value) { return min.compareTo(value) <= 0 && max.compareTo(value) >= 0; } /** * * @param other {@link Interval} to be added to this * @return new interval [ this.min + other.min , this.max + other.max ] */ public Interval add(Interval other) { return new Interval(min.add(other.min), max.add(other.max)); } /** * * @param other another {@link Interval} intersect with * @return intersection of this with other. returns null if intersection is * empty. */ public Interval intersect(Interval other) { return new Interval(min.max(other.min), max.min(other.max)); } /** * * @param other the other minmax to deal with * @return the range of values that, when added to a value from other, will * possibly get in our range. effectively, [min-other.max, * max-other.min]. Returns null if the resulting range is empty. */ public Interval invert(Interval other) { BigDecimal newmin = min.subtract(other.max); BigDecimal newmax = max.subtract(other.min); if (newmin.compareTo(newmax) > 0) return null; return new Interval(newmin, newmax); } /** * * @param value the value to subtract * @return Interval with both min and max reduced by value. */ public Interval subtract(BigDecimal value) { return new Interval(min.subtract(value), max.subtract(value)); } public Interval multiply(BigDecimal weight) { return new Interval(min.multiply(weight), max.multiply(weight)); } @Override public String toString() { return "Interval[" + min + "," + max + "]"; } /** * @param precision number of digits required * @return this but with modified precision. The interval is rounded so that * the new interval is inside the old one. */ public Interval round(int precision) { return new Interval(min.setScale(precision, RoundingMode.UP), max.setScale(precision, RoundingMode.DOWN)); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((max == null) ? 0 : max.hashCode()); result = prime * result + ((min == null) ? 0 : min.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Interval other = (Interval) obj; if (max == null) { if (other.max != null) return false; } else if (max.compareTo(other.max) != 0) // THIS WAS FIXED MANUALLY TO USE COMPARETO return false; if (min == null) { if (other.min != null) return false; } else if (min.compareTo(other.min) != 0) // THIS WAS FIXED MANUALLY TO USE COMPARETO return false; return true; } }