См. также:
для Microsoft Visual C:
http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=vs. 80% 29.aspx
и GCC утверждают совместимость с компилятором Microsoft .:
http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking -Pragmas.html
В дополнение к предыдущим ответам, обратите внимание, что независимо от упаковки в C ++ нет гарантий-распоряжений-членов. Компиляторы могут (и, конечно же, делать) добавлять в структуру элементов виртуальной таблицы и базовых структур. Даже существование виртуальной таблицы не обеспечивается стандартом (реализация виртуального механизма не указана), и поэтому можно сделать вывод, что такая гарантия просто невозможна.
Я вполне уверен, что порядок членов является гарантировано в C, но я не стал бы рассчитывать на это, когда писал кросс-платформенную или кросс-компиляторную программу.
Вы можете написать метод расширения:
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: методы расширения идут в статических классах - так как это довольно низкоуровневая функция, вероятно, это должно быть в каком-то основном пространстве имен в вашем проекте , Затем вы можете использовать этот метод в любом файле кода, который содержит директиву using для пространства имен, например
using Core.ExtensionMethods
int i = 4.Clamp(1, 3);
Начиная с .NET Core 2.0 System.Math
сейчас имеет метод Clamp
, который можно использовать вместо этого:
using System;
int i = Math.Clamp(4, 1, 3);
Используя предыдущие ответы, я сконфигурировал его ниже кода для моих нужд. Это также позволит вам зажимать число только по его min или 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;
}
}
Попробуйте:
public static int Clamp(int value, int min, int max)
{
return (value < min) ? min : (value > max) ? max : value;
}
В пространстве имен System.Math нет
http://msdn.microsoft.com/en-us/library/system.math_members.aspx
Существует класс MathHelper, где он доступен для игровой студии XNA, если это то, что вы делаете:
http://msdn.microsoft.com/ ан-нас / библиотека / bb197892 (v = XNAGameStudio.31) .aspx
Нет ни одного, но его не так сложно сделать. Я нашел здесь: clamp
Это:
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;
}
И его можно использовать как:
int i = Clamp(12, 10, 0); -> i == 10
double d = Clamp(4.5, 10.0, 0.0); -> d == 4.5
int a0 = x > a ? x : a; return a0 < b ? a0 : b
, который (хотя и дает правильные результаты) не совсем идеален.
– Mr. Smith
24 April 2014 в 04:25
Math.Min(Math.Max(x, min), max)
приводит к еще одному сравнению, чем необходимо, если x & lt; минимум
– Jim Balter
15 September 2015 в 05:58
Просто поделитесь решением Ли с вопросами и проблемами комментариев, где это возможно:
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;
}
Различия:
ed
), чтобы (далее) указать, что значение не зажато на месте, и вместо этого возвращается новое значение (см. Комментарий @ JimBalter ). null check
для всех входов (см. @ комментарий JeppeStigNielsen ). min
и max
, если min > max
(См. @ комментарий JeppeStigNielsen ). Ограничения: Без односторонних зажимов. Если max
- NaN
, всегда возвращается NaN
(см. комментарий Германа ).
IComparable
заключается в отсутствии бокса. Это должно происходить очень быстро. Помните, что сdouble
иfloat
методCompareTo
соответствует полному порядку, гдеNaN
меньше всех других значений, включаяNegativeInfinity
. Поэтому он не эквивалентен оператору<
. Если вы использовали<
с типом с плавающей точкой, вам также нужно будет рассмотреть, как относиться кNaN
. Это не относится к другим числовым типам. – Jeppe Stig Nielsen 7 August 2013 в 21:05NaN
в любом случае. Версия с<
и>
выводитNaN
, а использованиеNaN
дляmin
илиmax
эффективно сделает односторонний зажим. СCompareTo
он всегда будет возвращатьNaN
, еслиmax
-NaN
. – Herman 18 March 2014 в 12:12