我在哪里可以找到.NET中的"钳位"功能?

Dan*_*vil 84 c# clamp

我想将一个值钳位x到一个范围[a, b]:

x = (x < a) ? a : ((x > b) ? b : x);
Run Code Online (Sandbox Code Playgroud)

这是非常基本的.但是我没有在类库中看到函数"clamp" - 至少在类库中没有System.Math.

(因为不知道"钳制"一个值是为了确保它位于某些最大值和最小值之间.如果它大于最大值,则它被最大值替换,等等.)

Lee*_*Lee 122

你可以写一个扩展方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

编辑:扩展方法进入静态类 - 因为这是一个相当低级的函数,它可能应该放在项目的某个核心命名空间中.然后,您可以在包含命名空间的using指令的任何代码文件中使用该方法,例如

using Core.ExtensionMethods

int i = 4.Clamp(1, 3);
Run Code Online (Sandbox Code Playgroud)

.NET Core 2.0

从.NET Core 2.0开始,System.Math现在有一个Clamp可以使用的方法:

using System;

int i = Math.Clamp(4, 1, 3);
Run Code Online (Sandbox Code Playgroud)

  • 限制到`IComparable`的*generic*版本的好处是不会发生装箱.这应该跑得很快.请记住,使用`double`和`float`,`CompareTo`方法对应于`NaN`小于所有其他值的总顺序,包括`NegativeInfinity`.所以它不等同于`<`运算符.如果你使用带浮点类型的`<`,你也必须考虑如何处理`NaN`.这与其他数字类型无关. (4认同)

小智 25

尝试:

public static int Clamp(int value, int min, int max)  
{  
    return (value < min) ? min : (value > max) ? max : value;  
}
Run Code Online (Sandbox Code Playgroud)

  • @Larry,这怎么不可读?至少对我来说很好; +1 (16认同)
  • 啊! 那些丑陋的冗余括号!如果你将成为一个双三元运算符的邪恶天才,至少要正确地做到这一点并摆脱它们! (5认同)
  • @XenoRo那些"冗余"括号是使它可读的原因. (4认同)
  • @Cleaner - 1)如果你要求可读性,可以避免使用双三进制,而是使用IF块.2)你不开玩笑,是吗?的xD (2认同)

d7s*_*rai 24

只需使用Math.MinMath.Max:

x = Math.Min(Math.Max(x, a), b);
Run Code Online (Sandbox Code Playgroud)

  • 那为什么呢? (12认同)
  • @ d7samurai如果我们知道min <= max,`Math.Min(Math.Max(x,min),max)`如果x <min,则会导致比必要的更多的比较. (4认同)
  • 这对于您只需要执行一次的情况很有用,然后全新的功能感觉就像是一种矫枉过正的情况。 (2认同)

Jer*_* B. 13

没有一个,但制作一个并不难.我在这里找到了一个:

它是:

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;
    }
Run Code Online (Sandbox Code Playgroud)

它可以像:

int i = Clamp(12, 10, 0); -> i == 10
double d = Clamp(4.5, 10.0, 0.0); -> d == 4.5
Run Code Online (Sandbox Code Playgroud)

  • @CodeClown当值> max时,此解决方案会导致不必要的比较,并且反转的参数顺序会邀请(并且实际上保证)错误.我不知道你认为避免什么含糊不清. (6认同)

kem*_*002 10

System.Math命名空间中没有一个

http://msdn.microsoft.com/en-us/library/system.math_members.aspx

有一个MathHelper类可用于XNA游戏工作室,如果碰巧是你正在做的事情:

http://msdn.microsoft.com/en-us/library/bb197892(v=XNAGameStudio.31).aspx


juF*_*uFo 5

System.Math.Clamp如果您使用的是 .NET 5+、.NET Core 3.x 或 .NET Core 2.x,则这是您想要的方法。

var a = Math.Clamp(5, 1, 10); // = 5
var b = Math.Clamp(-99, 1, 10); // = 1
var c = Math.Clamp(99, 1, 10); // = 10
Run Code Online (Sandbox Code Playgroud)