我没有听说过,但是如果您将约束表示为间隔,则可以轻松地不使用它们:
x > 1000 变为 (1000, double.Infinity)
x == 1000 变为 [1000, 1000]
等等
这样你只需要一个类
class Constraint
{
double Lower; bool isLowerStrict;
double Upper; bool isUpperStrict;
bool isIn(double d)
{
return (isLowerStrict ? Lower < d : Lower <= d) &&
(isUpperStrict ? Upper > d : Upper >= d);
}
Constraint intersect(Constraint other)
{
Constraint result = new Constraint();
if (Lower > other.Lower)
{
result.Lower = Lower;
result.isLowerStrict = isLowerStrict;
}
else if (Lower < other.Lower)
{
result.Lower = other.Lower;
result.isLowerStrict = other.isLowerStrict;
}
else
{
result.Lower = Lower;
result.IsLowerStrict = isLowerStrict || other.isLowerStrict;
}
// the same for upper
return result;
}
public bool isEmpty()
{
if (Lower > Upper) return true;
if (Lower == Upper && (isLowerStrict || isUpperStrict)) return true;
return false;
}
public bool Equals(Constraint other)
{
if (isEmpty()) return other.isEmpty();
return (Lower == other.Lower) && (Upper = other.Upper) &&
(isLowerStrict == other.IsLowerStrict) &&
(isUpperStrict == other.isUpperStrict);
}
// construction:
static Constraint GreaterThan(double d)
{
return new Constraint()
{
Lower = d,
isLowerStrict = true,
Upper = double.PositiveInfinity,
isUpperStrict = false
};
}
static Constraint IsEqualTo(double d)
{
return new Constraint()
{
Lower = d,
isLowerStrict = false,
Upper = d,
isUpperStrict = false
};
}
// etc.
}
使用此代码,您可以回答以下问题:
1)重叠:a.Intersect(b).isEmpty()
2)相交:a.Intersect(b)
3) 约束:a.Intersect(b).Equals(a)
编辑:
正如@CodeInChaos 建议的那样,您应该考虑用十进制替换双精度。请注意,十进制缺少无限值,因此您应该改用 decimal.MaxValue 和 decimal.MinValue。