diff --git a/UnitsNet.Tests/UnitMathTests.cs b/UnitsNet.Tests/UnitMathTests.cs
index 014c8c65ea..67509044fd 100644
--- a/UnitsNet.Tests/UnitMathTests.cs
+++ b/UnitsNet.Tests/UnitMathTests.cs
@@ -156,26 +156,40 @@ public void SumOfLengthsWithSelectorCalculatesCorrectly()
}
[Fact]
- public void ClampCalculatesCorrectly()
+ public void Clamp_ReturnsValue_WhenWithinBounds()
{
var min = Length.FromMeters(-1);
var max = Length.FromCentimeters(150);
-
- var value1 = Length.FromMillimeters(33);
-
- Length clampedValue = UnitMath.Clamp(value1, min, max);
+ var value = Length.FromMillimeters(33);
+
+ Length clampedValue = UnitMath.Clamp(value, min, max);
+
Assert.Equal(33, clampedValue.Value);
Assert.Equal(LengthUnit.Millimeter, clampedValue.Unit);
+ }
- var value2 = Length.FromMillimeters(-1500);
-
- Length clampedMin = UnitMath.Clamp(value2, min, max);
+ [Fact]
+ public void Clamp_ReturnsMinAsValueUnit_WhenValueIsBelowMin()
+ {
+ var min = Length.FromMeters(-1);
+ var max = Length.FromCentimeters(150);
+ var value = Length.FromMillimeters(-1500);
+
+ Length clampedMin = UnitMath.Clamp(value, min, max);
+
Assert.Equal(-1000, clampedMin.Value);
Assert.Equal(LengthUnit.Millimeter, clampedMin.Unit);
+ }
- var value3 = Length.FromMillimeters(2000);
-
- Length clampedMax = UnitMath.Clamp(value3, min, max);
+ [Fact]
+ public void Clamp_ReturnsMaxAsValueUnit_WhenValueIsAboveMax()
+ {
+ var min = Length.FromMeters(-1);
+ var max = Length.FromCentimeters(150);
+ var value = Length.FromMillimeters(2000);
+
+ Length clampedMax = UnitMath.Clamp(value, min, max);
+
Assert.Equal(1500, clampedMax.Value);
Assert.Equal(LengthUnit.Millimeter, clampedMax.Unit);
}
diff --git a/UnitsNet/UnitMath.cs b/UnitsNet/UnitMath.cs
index 38c7246201..a6fb77465b 100644
--- a/UnitsNet/UnitMath.cs
+++ b/UnitsNet/UnitMath.cs
@@ -1,76 +1,96 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
+namespace UnitsNet;
-namespace UnitsNet
+///
+/// Extension methods for common math operations.
+///
+public static class UnitMath
{
+ /// Returns the smaller of two values.
+ /// The type of quantities to compare.
+ /// The first of two values to compare.
+ /// The second of two values to compare.
+ /// Parameter or , whichever is smaller.
+ public static TQuantity Min(TQuantity val1, TQuantity val2)
+ where TQuantity : IQuantity, IComparable
+ {
+ return val1.CompareTo(val2) == 1 ? val2 : val1;
+ }
+
+ /// Returns the larger of two values.
+ /// The type of quantities to compare.
+ /// The first of two values to compare.
+ /// The second of two values to compare.
+ /// Parameter or , whichever is larger.
+ public static TQuantity Max(TQuantity val1, TQuantity val2)
+ where TQuantity : IQuantity, IComparable
+ {
+ return val1.CompareTo(val2) == -1 ? val2 : val1;
+ }
+
///
- /// A set of extension methods for some of the most common Math operations, such as Min, Max, Sum and Average
+ /// Clamps the specified to the inclusive range defined by and
+ /// .
///
- public static class UnitMath
+ ///
+ /// The type of the quantity, which must implement and
+ /// .
+ ///
+ /// The value to clamp.
+ /// The minimum allowable value.
+ /// The maximum allowable value.
+ ///
+ /// The clamped value:
+ ///
+ /// -
+ ///
+ /// if it lies within the range [,
+ /// ].
+ ///
+ ///
+ /// -
+ ///
+ /// (converted to value.Unit) if is less than
+ /// .
+ ///
+ ///
+ /// -
+ ///
+ /// (converted to value.Unit) if is greater than
+ /// .
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// Thrown if is greater than .
+ ///
+ public static TQuantity Clamp(TQuantity value, TQuantity min, TQuantity max)
+ where TQuantity : IQuantityOfType, IComparable
{
- /// Returns the smaller of two values.
- /// The type of quantities to compare.
- /// The first of two values to compare.
- /// The second of two values to compare.
- /// Parameter or , whichever is smaller.
- public static TQuantity Min(TQuantity val1, TQuantity val2)
- where TQuantity : IQuantity, IComparable
+ UnitKey unitKey = value.UnitKey;
+#if NET
+ TQuantity minValue = TQuantity.Create(min.As(unitKey), unitKey);
+ TQuantity maxValue = TQuantity.Create(max.As(unitKey), unitKey);
+#else
+ TQuantity minValue = value.QuantityInfo.Create(min.As(unitKey), unitKey);
+ TQuantity maxValue = value.QuantityInfo.Create(max.As(unitKey), unitKey);
+#endif
+
+ if (minValue.CompareTo(maxValue) > 0)
{
- return val1.CompareTo(val2) == 1 ? val2 : val1;
+ throw new ArgumentException($"min ({min}) cannot be greater than max ({max})", nameof(min));
}
- /// Returns the larger of two values.
- /// The type of quantities to compare.
- /// The first of two values to compare.
- /// The second of two values to compare.
- /// Parameter or , whichever is larger.
- public static TQuantity Max(TQuantity val1, TQuantity val2)
- where TQuantity : IQuantity, IComparable
+ if (value.CompareTo(minValue) < 0)
{
- return val1.CompareTo(val2) == -1 ? val2 : val1;
+ return minValue;
}
-
- /// Returns clamped to the inclusive range of and .
- /// The value to be clamped.
- /// The lower bound of the result.
- /// The upper bound of the result.
- ///
- /// if ≤ ≤ .
- ///
- /// -or-
- ///
- /// (converted to value.Unit) if < .
- ///
- /// -or-
- ///
- /// (converted to value.Unit) if < .
- ///
- ///
- /// cannot be greater than .
- ///
- public static TQuantity Clamp(TQuantity value, TQuantity min, TQuantity max) where TQuantity : IComparable, IQuantity
- {
- var minValue = (TQuantity)min.ToUnit(value.Unit);
- var maxValue = (TQuantity)max.ToUnit(value.Unit);
-
- if (minValue.CompareTo(maxValue) > 0)
- {
- throw new ArgumentException($"min ({min}) cannot be greater than max ({max})", nameof(min));
- }
-
- if (value.CompareTo(minValue) < 0)
- {
- return minValue;
- }
- if (value.CompareTo(maxValue) > 0)
- {
- return maxValue;
- }
-
- return value;
+ if (value.CompareTo(maxValue) > 0)
+ {
+ return maxValue;
}
+
+ return value;
}
}