modulo method
Modulo operation on two intervals.
Returns top if the divisor interval contains zero.
Implementation
IntervalDomain modulo(IntervalDomain other) {
if (isBottom || other.isBottom) return bottomValue;
// Modulo by interval containing zero is undefined
if (other.containsValue(0)) {
return topValue;
}
// If either is infinite, result is bounded by divisor
if (min == null || max == null || other.min == null || other.max == null) {
// Result of a % b is in range [0, |b|-1] for positive a
// or [-(|b|-1), |b|-1] for possibly negative a
final maxDivisor = other.max?.abs();
if (maxDivisor == null) return topValue;
if (min != null && min! >= 0) {
// Non-negative dividend: result is in [0, |b|-1]
return IntervalDomain(0, maxDivisor - 1);
}
// Possibly negative dividend: result spans negative to positive
return IntervalDomain(-(maxDivisor - 1), maxDivisor - 1);
}
// All bounds are finite
final maxDivisor = math.max(other.min!.abs(), other.max!.abs());
if (min! >= 0) {
// Non-negative dividend
return IntervalDomain(0, math.min(max!, maxDivisor - 1));
} else if (max! < 0) {
// Strictly negative dividend
return IntervalDomain(math.max(min!, -(maxDivisor - 1)), 0);
} else {
// Spans zero
return IntervalDomain(
math.max(min!, -(maxDivisor - 1)),
math.min(max!, maxDivisor - 1),
);
}
}