El siguiente código admite la especificación de límites en cualquier orden (es decir bound1 <= bound2
, o bound2 <= bound1
). Encontré esto útil para fijar valores calculados a partir de ecuaciones lineales ( y=mx+b
) donde la pendiente de la línea puede aumentar o disminuir.
Lo sé: el código consta de cinco operadores de expresión condicional súper feos . La cosa es que funciona , y las pruebas a continuación lo demuestran. No dude en agregar paréntesis estrictamente innecesarios si así lo desea.
Puede crear fácilmente otras sobrecargas para otros tipos numéricos y básicamente copiar / pegar las pruebas.
Advertencia: comparar números de punto flotante no es sencillo. Este código no implementa double
comparaciones de manera sólida. Utilice una biblioteca de comparación de punto flotante para reemplazar los usos de los operadores de comparación.
public static class MathExtensions
{
public static double Clamp(this double value, double bound1, double bound2)
{
return bound1 <= bound2 ? value <= bound1 ? bound1 : value >= bound2 ? bound2 : value : value <= bound2 ? bound2 : value >= bound1 ? bound1 : value;
}
}
Pruebas de xUnit / FluentAssertions:
public class MathExtensionsTests
{
[Theory]
[InlineData(0, 0, 0, 0)]
[InlineData(0, 0, 2, 0)]
[InlineData(-1, 0, 2, 0)]
[InlineData(1, 0, 2, 1)]
[InlineData(2, 0, 2, 2)]
[InlineData(3, 0, 2, 2)]
[InlineData(0, 2, 0, 0)]
[InlineData(-1, 2, 0, 0)]
[InlineData(1, 2, 0, 1)]
[InlineData(2, 2, 0, 2)]
[InlineData(3, 2, 0, 2)]
public void MustClamp(double value, double bound1, double bound2, double expectedValue)
{
value.Clamp(bound1, bound2).Should().Be(expectedValue);
}
}