diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs index e1ad5e6377a2cb..105ded07251522 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Double.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs @@ -940,14 +940,20 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati /// public static double Clamp(double value, double min, double max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } return Min(Max(value, min), max); } /// public static double ClampNative(double value, double min, double max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } return MinNative(MaxNative(value, min), max); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index 06848fad3a90bc..f1e653e60e1fa5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -1644,7 +1644,10 @@ public static int ILogB(Half x) /// public static Half ClampNative(Half value, Half min, Half max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } return MinNative(MaxNative(value, min), max); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Int128.cs b/src/libraries/System.Private.CoreLib/src/System/Int128.cs index 8e252d58da0ffc..bfc8e8c8bf0e25 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int128.cs @@ -1201,7 +1201,10 @@ public static Int128 BigMul(Int128 left, Int128 right, out Int128 lower) /// public static Int128 Clamp(Int128 value, Int128 min, Int128 max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } if (value < min) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index c48fee2fee07ef..b69ad824a68c76 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -525,7 +525,10 @@ public static decimal Ceiling(decimal d) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte Clamp(byte value, byte min, byte max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -542,7 +545,10 @@ public static byte Clamp(byte value, byte min, byte max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static decimal Clamp(decimal value, decimal min, decimal max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -559,7 +565,10 @@ public static decimal Clamp(decimal value, decimal min, decimal max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Clamp(double value, double min, double max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -576,7 +585,10 @@ public static double Clamp(double value, double min, double max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short Clamp(short value, short min, short max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -593,7 +605,10 @@ public static short Clamp(short value, short min, short max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Clamp(int value, int min, int max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -610,7 +625,10 @@ public static int Clamp(int value, int min, int max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Clamp(long value, long min, long max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -642,7 +660,10 @@ public static long Clamp(long value, long min, long max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static nint Clamp(nint value, nint min, nint max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -660,7 +681,10 @@ public static nint Clamp(nint value, nint min, nint max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte Clamp(sbyte value, sbyte min, sbyte max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -677,7 +701,10 @@ public static sbyte Clamp(sbyte value, sbyte min, sbyte max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Clamp(float value, float min, float max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -695,7 +722,10 @@ public static float Clamp(float value, float min, float max) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort Clamp(ushort value, ushort min, ushort max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -713,7 +743,10 @@ public static ushort Clamp(ushort value, ushort min, ushort max) [CLSCompliant(false)] public static uint Clamp(uint value, uint min, uint max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -731,7 +764,10 @@ public static uint Clamp(uint value, uint min, uint max) [CLSCompliant(false)] public static ulong Clamp(ulong value, ulong min, ulong max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -764,7 +800,10 @@ public static ulong Clamp(ulong value, ulong min, ulong max) [CLSCompliant(false)] public static nuint Clamp(nuint value, nuint min, nuint max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -1457,7 +1496,7 @@ public static unsafe double Truncate(double d) [DoesNotReturn] internal static void ThrowMinMaxException(T min, T max) { - throw new ArgumentOutOfRangeException(nameof(max), max, SR.Format(SR.ArgumentOutOfRange_Generic_MustBeGreaterOrEqual, nameof(max), max, min)); + throw new ArgumentException(SR.Format(SR.Argument_MinMaxValue, min, max)); } public static double ScaleB(double x, int n) diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs index 05b8346e7b8561..5b95aa41dcc757 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Single.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs @@ -937,14 +937,20 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinatio /// public static float Clamp(float value, float min, float max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } return Min(Max(value, min), max); } /// public static float ClampNative(float value, float min, float max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } return MinNative(MaxNative(value, min), max); } diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs index 6fb1cf7665f47f..b76e5a04f5ce11 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs @@ -1399,7 +1399,10 @@ public static UInt128 BigMul(UInt128 left, UInt128 right, out UInt128 lower) /// public static UInt128 Clamp(UInt128 value, UInt128 min, UInt128 max) { - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } if (value < min) { diff --git a/src/libraries/System.Runtime.Numerics/src/Resources/Strings.resx b/src/libraries/System.Runtime.Numerics/src/Resources/Strings.resx index d0330116f7c43c..de58906e0a7dde 100644 --- a/src/libraries/System.Runtime.Numerics/src/Resources/Strings.resx +++ b/src/libraries/System.Runtime.Numerics/src/Resources/Strings.resx @@ -69,6 +69,9 @@ With the AllowHexSpecifier bit set in the enum bit field, the only other valid bits that can be combined into the enum value must be a subset of those in HexNumber. + + '{0}' cannot be greater than {1}. + The parameter must be a BigInteger. diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs index 4074e66b85af46..b5787cc243b2f4 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs @@ -3947,7 +3947,10 @@ public static BigInteger Clamp(BigInteger value, BigInteger min, BigInteger max) min.AssertValid(); max.AssertValid(); - ArgumentOutOfRangeException.ThrowIfLessThan(max, min); + if (min > max) + { + ThrowMinMaxException(min, max); + } if (value < min) { @@ -3959,6 +3962,12 @@ public static BigInteger Clamp(BigInteger value, BigInteger min, BigInteger max) } return value; + + [DoesNotReturn] + static void ThrowMinMaxException(T min, T max) + { + throw new ArgumentException(SR.Format(SR.Argument_MinMaxValue, min, max)); + } } /// diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Math.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Math.cs index b1108b0c95de47..316650591fd64f 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Math.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/Math.cs @@ -2212,20 +2212,20 @@ public static void Clamp_Decimal(decimal value, decimal min, decimal max, decima } [Fact] - public static void Clamp_MinGreaterThanMax_ThrowsArgumentOutOfRangeException() - { - AssertExtensions.Throws("max", () => Math.Clamp((sbyte)1, (sbyte)2, (sbyte)1)); - AssertExtensions.Throws("max", () => Math.Clamp((byte)1, (byte)2, (byte)1)); - AssertExtensions.Throws("max", () => Math.Clamp((short)1, (short)2, (short)1)); - AssertExtensions.Throws("max", () => Math.Clamp((ushort)1, (ushort)2, (ushort)1)); - AssertExtensions.Throws("max", () => Math.Clamp((int)1, (int)2, (int)1)); - AssertExtensions.Throws("max", () => Math.Clamp((uint)1, (uint)2, (uint)1)); - AssertExtensions.Throws("max", () => Math.Clamp((long)1, (long)2, (long)1)); - AssertExtensions.Throws("max", () => Math.Clamp((ulong)1, (ulong)2, (ulong)1)); - - AssertExtensions.Throws("max", () => Math.Clamp((float)1, (float)2, (float)1)); - AssertExtensions.Throws("max", () => Math.Clamp((double)1, (double)2, (double)1)); - AssertExtensions.Throws("max", () => Math.Clamp((decimal)1, (decimal)2, (decimal)1)); + public static void Clamp_MinGreaterThanMax_ThrowsArgumentException() + { + AssertExtensions.Throws(null, () => Math.Clamp((sbyte)1, (sbyte)2, (sbyte)1)); + AssertExtensions.Throws(null, () => Math.Clamp((byte)1, (byte)2, (byte)1)); + AssertExtensions.Throws(null, () => Math.Clamp((short)1, (short)2, (short)1)); + AssertExtensions.Throws(null, () => Math.Clamp((ushort)1, (ushort)2, (ushort)1)); + AssertExtensions.Throws(null, () => Math.Clamp((int)1, (int)2, (int)1)); + AssertExtensions.Throws(null, () => Math.Clamp((uint)1, (uint)2, (uint)1)); + AssertExtensions.Throws(null, () => Math.Clamp((long)1, (long)2, (long)1)); + AssertExtensions.Throws(null, () => Math.Clamp((ulong)1, (ulong)2, (ulong)1)); + + AssertExtensions.Throws(null, () => Math.Clamp((float)1, (float)2, (float)1)); + AssertExtensions.Throws(null, () => Math.Clamp((double)1, (double)2, (double)1)); + AssertExtensions.Throws(null, () => Math.Clamp((decimal)1, (decimal)2, (decimal)1)); } [Theory]