diff --git a/PreciseNumber.Test/PreciseNumberTests.cs b/PreciseNumber.Test/PreciseNumberTests.cs index 10ea1d1..33a43bb 100644 --- a/PreciseNumber.Test/PreciseNumberTests.cs +++ b/PreciseNumber.Test/PreciseNumberTests.cs @@ -84,6 +84,25 @@ public void TestClampLower() Assert.AreEqual(min, result); } + [TestMethod] + public void TestClampThrowsWhenMinIsGreaterThanMax() + { + PreciseNumber min = 3.ToPreciseNumber(); + PreciseNumber max = 1.ToPreciseNumber(); + + // Every value, inside or outside the inverted range, is a caller bug, as it is for Math.Clamp. + Assert.ThrowsExactly(() => PreciseNumber.Clamp(2.ToPreciseNumber(), min, max)); + Assert.ThrowsExactly(() => PreciseNumber.Clamp(5.ToPreciseNumber(), min, max)); + Assert.ThrowsExactly(() => 2.ToPreciseNumber().Clamp(3, 1)); + } + + [TestMethod] + public void TestClampAcceptsEqualBounds() + { + PreciseNumber bound = 3.ToPreciseNumber(); + Assert.AreEqual(bound, PreciseNumber.Clamp(7.ToPreciseNumber(), bound, bound)); + } + [TestMethod] public void TestClampUpper() { diff --git a/PreciseNumber/PreciseNumber.cs b/PreciseNumber/PreciseNumber.cs index fc17624..cb43ef7 100644 --- a/PreciseNumber/PreciseNumber.cs +++ b/PreciseNumber/PreciseNumber.cs @@ -572,11 +572,17 @@ public PreciseNumber Round(int decimalDigits) /// The minimum value. /// The maximum value. /// The clamped value. + /// is greater than . public PreciseNumber Clamp(TNumber min, TNumber max) where TNumber : INumber { PreciseNumber sigMin = min.ToPreciseNumber(); PreciseNumber sigMax = max.ToPreciseNumber(); + if (sigMin > sigMax) + { + throw new ArgumentException($"'{sigMin}' cannot be greater than {sigMax}.", nameof(min)); + } + PreciseNumber clampedToMax = this > sigMax ? sigMax : this; return this < sigMin ? sigMin : clampedToMax; } @@ -1710,6 +1716,7 @@ public static bool NotEqual(PreciseNumber left, PreciseNumber right) => /// The minimum value. /// The maximum value. /// The clamped number. + /// is greater than . public static PreciseNumber Clamp(PreciseNumber value, PreciseNumber min, PreciseNumber max) => value.Clamp(min, max);