I would like to clamp a value x
to a range [a, b]
:
我想将一个值x固定到一个范围[a, b]:
x = (x < a) ? a : ((x > b) ? b : x);
This is quite basic. But I do not see a function "clamp" in the class library - at least not in System.Math
.
这是很基本的。但我在类库中看不到“箝位”函数——至少在System.Math中看不到。
(For the unaware to "clamp" a value is to make sure that it lies between some maximum and minimum values. If it’s greater than the max value, then it’s replaced by the max, etc.)
(对于不知道“夹”的值,则要确保它位于某些最大值和最小值之间。如果它大于最大值,那么它就被最大值所代替)
7 个解决方案
#1
91
You could write an extension method:
你可以写一个扩展方法:
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
if (val.CompareTo(min) < 0) return min;
else if(val.CompareTo(max) > 0) return max;
else return val;
}
EDIT: Extension methods go in static classes - since this is quite a low-level function, it should probably go in some core namespace in your project. You can then use the method in any code file that contains a using directive for the namespace e.g.
编辑:扩展方法进入静态类——因为这是一个相当低级的函数,它可能应该进入项目中的一些核心名称空间。然后,您可以在任何包含名称空间使用指令的代码文件中使用该方法。
using Core.ExtensionMethods
int i = 4.Clamp(1, 3);
.NET Core 2.0
Starting with .NET Core 2.0 System.Math
now has a Clamp
method that can be used instead:
从。net Core 2.0系统开始。Math现在有了一种箝位方法,可以用来代替:
using System;
int i = Math.Clamp(4, 1, 3);
#2
23
Try:
试一试:
public static int Clamp(int value, int min, int max)
{
return (value < min) ? min : (value > max) ? max : value;
}
#3
17
Just use Math.Min
and Math.Max
:
用数学。最小值和Math.Max:
x = Math.Min(Math.Max(x, a), b);
#4
11
There isn't one, but it's not too hard to make one. I found one here: clamp
没有,但做一个并不难。我在这里找到一个:钳子
It is:
它是:
public static T Clamp<T>(T value, T max, T min)
where T : System.IComparable<T> {
T result = value;
if (value.CompareTo(max) > 0)
result = max;
if (value.CompareTo(min) < 0)
result = min;
return result;
}
And it can be used like:
可以这样使用:
int i = Clamp(12, 10, 0); -> i == 10
double d = Clamp(4.5, 10.0, 0.0); -> d == 4.5
#5
10
There isn't one in the System.Math namespace
系统中没有。数学名称空间
http://msdn.microsoft.com/en-us/library/system.math_members.aspx
http://msdn.microsoft.com/en-us/library/system.math_members.aspx
There is a MathHelper Class where it is available for the XNA game studio if that happens to be what you are doing:
有一个MathHelper类,它可以用于XNA游戏工作室,如果这恰好是你正在做的事情:
http://msdn.microsoft.com/en-us/library/bb197892(v=XNAGameStudio.31).aspx
http://msdn.microsoft.com/en-us/library/bb197892(v = XNAGameStudio.31). aspx
#6
2
Just sharing Lee's solution with the comments' issues and concerns addressed, where possible:
只要在可能的情况下,把李的解决方案与评论中提出的问题和关注分享给大家:
public static T Clamped<T>(this T value, T min, T max) where T : IComparable<T> {
if (value == null) throw new ArgumentNullException(nameof(value), "is null.");
if (min == null) throw new ArgumentNullException(nameof(min), "is null.");
if (max == null) throw new ArgumentNullException(nameof(max), "is null.");
//If min <= max, clamp
if (min.CompareTo(max) <= 0) return value.CompareTo(min) < 0 ? min : value.CompareTo(max) > 0 ? max : value;
//If min > max, clamp on swapped min and max
return value.CompareTo(max) < 0 ? max : value.CompareTo(min) > 0 ? min : value;
}
Differences:
差异:
- Method name uses the appropriate verb tense (
ed
) to (further) indicate that the value is not clamped in-place, and that, instead, a new value is returned (See @JimBalter's comment). - 方法名使用适当的动词时态(ed)来(进一步)表示该值没有被固定在适当的位置,而是返回一个新的值(参见@JimBalter的注释)。
- Does appropriate
null check
on all inputs (See @JeppeStigNielsen's comment). - 对所有输入执行适当的null检查(参见@JeppeStigNielsen的评论)。
- Swaps
min
andmax
ifmin > max
(See @JeppeStigNielsen's comment). - 如果min > max,则交换min和max(见@JeppeStigNielsen的评论)。
Limitations: No one-sided clamps. If max
is NaN
, always returns NaN
(See Herman's comment).
限制:不片面的夹子。如果max是NaN,总是返回NaN(见Herman的评论)。
#7
0
Using the previous answers, I condensed it down to the below code for my needs. This will also allow you to clamp a number only by its min or max.
使用前面的答案,我将它压缩为下面的代码以满足我的需要。这也将允许您仅通过它的最小或最大值来限制一个数字。
public static class IComparableExtensions
{
public static T Clamped<T>(this T value, T min, T max)
where T : IComparable<T>
{
return value.CompareTo(min) < 0 ? min : value.ClampedMaximum(max);
}
public static T ClampedMinimum<T>(this T value, T min)
where T : IComparable<T>
{
return value.CompareTo(min) < 0 ? min : value;
}
public static T ClampedMaximum<T>(this T value, T max)
where T : IComparable<T>
{
return value.CompareTo(max) > 0 ? max : value;
}
}
#1
91
You could write an extension method:
你可以写一个扩展方法:
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
if (val.CompareTo(min) < 0) return min;
else if(val.CompareTo(max) > 0) return max;
else return val;
}
EDIT: Extension methods go in static classes - since this is quite a low-level function, it should probably go in some core namespace in your project. You can then use the method in any code file that contains a using directive for the namespace e.g.
编辑:扩展方法进入静态类——因为这是一个相当低级的函数,它可能应该进入项目中的一些核心名称空间。然后,您可以在任何包含名称空间使用指令的代码文件中使用该方法。
using Core.ExtensionMethods
int i = 4.Clamp(1, 3);
.NET Core 2.0
Starting with .NET Core 2.0 System.Math
now has a Clamp
method that can be used instead:
从。net Core 2.0系统开始。Math现在有了一种箝位方法,可以用来代替:
using System;
int i = Math.Clamp(4, 1, 3);
#2
23
Try:
试一试:
public static int Clamp(int value, int min, int max)
{
return (value < min) ? min : (value > max) ? max : value;
}
#3
17
Just use Math.Min
and Math.Max
:
用数学。最小值和Math.Max:
x = Math.Min(Math.Max(x, a), b);
#4
11
There isn't one, but it's not too hard to make one. I found one here: clamp
没有,但做一个并不难。我在这里找到一个:钳子
It is:
它是:
public static T Clamp<T>(T value, T max, T min)
where T : System.IComparable<T> {
T result = value;
if (value.CompareTo(max) > 0)
result = max;
if (value.CompareTo(min) < 0)
result = min;
return result;
}
And it can be used like:
可以这样使用:
int i = Clamp(12, 10, 0); -> i == 10
double d = Clamp(4.5, 10.0, 0.0); -> d == 4.5
#5
10
There isn't one in the System.Math namespace
系统中没有。数学名称空间
http://msdn.microsoft.com/en-us/library/system.math_members.aspx
http://msdn.microsoft.com/en-us/library/system.math_members.aspx
There is a MathHelper Class where it is available for the XNA game studio if that happens to be what you are doing:
有一个MathHelper类,它可以用于XNA游戏工作室,如果这恰好是你正在做的事情:
http://msdn.microsoft.com/en-us/library/bb197892(v=XNAGameStudio.31).aspx
http://msdn.microsoft.com/en-us/library/bb197892(v = XNAGameStudio.31). aspx
#6
2
Just sharing Lee's solution with the comments' issues and concerns addressed, where possible:
只要在可能的情况下,把李的解决方案与评论中提出的问题和关注分享给大家:
public static T Clamped<T>(this T value, T min, T max) where T : IComparable<T> {
if (value == null) throw new ArgumentNullException(nameof(value), "is null.");
if (min == null) throw new ArgumentNullException(nameof(min), "is null.");
if (max == null) throw new ArgumentNullException(nameof(max), "is null.");
//If min <= max, clamp
if (min.CompareTo(max) <= 0) return value.CompareTo(min) < 0 ? min : value.CompareTo(max) > 0 ? max : value;
//If min > max, clamp on swapped min and max
return value.CompareTo(max) < 0 ? max : value.CompareTo(min) > 0 ? min : value;
}
Differences:
差异:
- Method name uses the appropriate verb tense (
ed
) to (further) indicate that the value is not clamped in-place, and that, instead, a new value is returned (See @JimBalter's comment). - 方法名使用适当的动词时态(ed)来(进一步)表示该值没有被固定在适当的位置,而是返回一个新的值(参见@JimBalter的注释)。
- Does appropriate
null check
on all inputs (See @JeppeStigNielsen's comment). - 对所有输入执行适当的null检查(参见@JeppeStigNielsen的评论)。
- Swaps
min
andmax
ifmin > max
(See @JeppeStigNielsen's comment). - 如果min > max,则交换min和max(见@JeppeStigNielsen的评论)。
Limitations: No one-sided clamps. If max
is NaN
, always returns NaN
(See Herman's comment).
限制:不片面的夹子。如果max是NaN,总是返回NaN(见Herman的评论)。
#7
0
Using the previous answers, I condensed it down to the below code for my needs. This will also allow you to clamp a number only by its min or max.
使用前面的答案,我将它压缩为下面的代码以满足我的需要。这也将允许您仅通过它的最小或最大值来限制一个数字。
public static class IComparableExtensions
{
public static T Clamped<T>(this T value, T min, T max)
where T : IComparable<T>
{
return value.CompareTo(min) < 0 ? min : value.ClampedMaximum(max);
}
public static T ClampedMinimum<T>(this T value, T min)
where T : IComparable<T>
{
return value.CompareTo(min) < 0 ? min : value;
}
public static T ClampedMaximum<T>(this T value, T max)
where T : IComparable<T>
{
return value.CompareTo(max) > 0 ? max : value;
}
}