Clamping Values
22 Jun 2013 by Nigel SampsonIn last week’s post on building the iOS 7 parallax background in Windows Phone I commented on the fact I was surprised there wasn’t a Clamp function on the Math class.
For those who aren’t sure of the term it originates (I believe) out of computer graphics and ensures a value lies between a range of values. In essence it combines the Min and Max functions so that a simple implementation of Clamp could look like.
public static double Clamp(double value, double minimum, double maximum)
{
return Math.Max(minimum, Math.Min(maximum, value));
}
Rather than write this method for each different type we can make use of the built in interface IComparable and create a generic clamp method that looks like:
public static T Clamp<T>(this T value, T minimum, T maximum)
where T : IComparable<T>
{
if (value.CompareTo(minimum) < 0)
return minimum;
if (value.CompareTo(maximum) > 0)
return maximum;
return value;
}
The great thing about it being generic off the IComparable interface is it works on any class implementing the interface including types like TimeSpan.
[TestMethod]
public void ClampTimeSpanWithValueBelowRangeReturnsMinimum()
{
var value = TimeSpan.FromSeconds(10);
var clamped = value.Clamp(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(30));
Assert.AreEqual(TimeSpan.FromSeconds(20), clamped);
}