Как ограничить значение переменной в c
Перейти к содержимому

Как ограничить значение переменной в c

  • автор:

Как ограничить значение переменной в data class-е?

Как сделать так, чтобы int status из HistoryItem мог быть установлен только на значение из Statuses?

  • Вопрос задан более двух лет назад
  • 82 просмотра

Комментировать

Решения вопроса 1

Java, Kotlin, Android Developer

Использвать enum вместо инта.
Вроде последняя версия room умеет автоматом работать с enum. Если нет, можно написать адаптер.

Ответ написан более двух лет назад

Комментировать

Нравится 1 Комментировать

Ответы на вопрос 0

Ваш ответ на вопрос

Войдите, чтобы написать ответ

android

  • Android
  • +1 ещё

Как корректно реализовать Базу данных в приложении на Андроид?

  • 1 подписчик
  • вчера
  • 42 просмотра

Пределы целых чисел в C и C++

Ограничения для целочисленных типов в C и C++ представлены в следующей таблице. Эти ограничения заданы в стандартном файле заголовка C . Стандартный файл заголовка C++ содержит , который включает в себя .

В Microsoft C также допускается объявление целочисленных переменных с указанием размера, которые относятся к целочисленным типам с размером 8, 16, 32 или 64 бит. Дополнительные сведения о них см. в статье Целочисленные типы с указанием размера.

Ограничения для целочисленных констант

Константа Значение Значение
CHAR_BIT Количество битов в наименьшей переменной, которая не является битовым полем. 8
SCHAR_MIN Минимальное значение для переменной типа signed char . –128
SCHAR_MAX Максимальное значение для переменной типа signed char . 127
UCHAR_MAX Максимальное значение для переменной типа unsigned char . 255 (0xff)
CHAR_MIN Минимальное значение для переменной типа char . –128 (или 0, если используется параметр /J)
CHAR_MAX Максимальное значение для переменной типа char . –127 (или 255, если используется параметр /J)
MB_LEN_MAX Максимальное число байтов в многобайтовом символе. 5
SHRT_MIN Минимальное значение для переменной типа short . -32768
SHRT_MAX Максимальное значение для переменной типа short . 32767
USHRT_MAX Максимальное значение для переменной типа unsigned short . 65 535 (0xffff)
INT_MIN Минимальное значение для переменной типа int . -2147483647 — 1
INT_MAX Максимальное значение для переменной типа int . 2147483647
UINT_MAX Максимальное значение для переменной типа unsigned int . 4 294 967 295 (0xffffffff)
LONG_MIN Минимальное значение для переменной типа long . -2147483647 — 1
LONG_MAX Максимальное значение для переменной типа long . 2147483647
ULONG_MAX Максимальное значение для переменной типа unsigned long . 4 294 967 295 (0xffffffff)
LLONG_MIN Минимальное значение для переменной типа long long . –9 223 372 036 854 775 807 – 1
LLONG_MAX Максимальное значение для переменной типа long long . 9 223 372 036 854 775 807
ULLONG_MAX Максимальное значение для переменной типа unsigned long long . 18 446 744 073 709 551 615 (0xffffffffffffffff)

Если значение превышает максимально возможное представление целочисленного типа, компилятор Microsoft выдает ошибку.

Завершение блока, относящегося только к системам Майкрософт

Как ограничить значение переменной в c

Ограничивает значение переменной заданными пределами.

Параметры

x: переменная, значение которой необходимо ограничить, любой тип данных

a: нижний предел, любой тип данных

b: верхний предел, любой тип данных

Возвращаемые значения

x: если x лежит в пределах между a и b.

a: если x меньше a.

b: если x больше b.

Пример

sensVal = constrain(sensVal, 10, 150); // числовые показания датчика ограничены диапазоном от 10 до 150

Ограничение верхнего значения переменной

Если вы имеете в виду эффективность, современные компиляторы убирают переходы при оптимизации (проверил на MSVC и gcc).

24 фев 2016 в 0:03

Имеется в виду сложение с насыщением (saturation), т.е. 250+6=255 ? Или результатом сложения может быть любое число, не большее 255? А сами A и B могут быть больше 255?

24 фев 2016 в 6:18
Думаю, что имеется в виду это решение: stackoverflow.com/questions/5277623/…
24 фев 2016 в 12:14

4 ответа 4

Сортировка: Сброс на вариант по умолчанию

Отказ от использования if возможен только в таких случаях:

  • наивный преподаватель. Но это решается административными методами.
  • внутреннее чувство несовершенности. Это решается психологом.
  • нужда в оптимизации, так как профайлер сказал, что это узкое место. Вот этим мы и займемся.

Раз это узкое место, то значит оно часто вызывается, например в цикле. Есть ряд задач на переконвертирование картинок (видео), где нужно выполнять подобную операцию, например, изменять яркость. И современные процессоры предоставляют готовую инструкцию, которая как раз подобное и делает — складывает числа с насыщением. Имя этим инструкциям — SSE2. Эти инструкции поддерживаются практически всеми существующими на данный момент процессорами, а 8 винда и старше даже не будет устанавливаться, если процессор их не поддерживает. Так что тут бояться не стоит.

Но не нужно думать, что нужно будет писать явно ассемблерный код. Для этого придумали чудную штуку — интринсики. Это такие «магические» функции, которые компилятор знает и вместо них, почти один к одному подставляет ассемблерный код.

Перейдем ближе к делу. В приведенном в вопросе случае нужна функция _mm_adds_epu8. Как видно с текста, поддерживается даже 2005 студией (а также всеми современными gcc). Эта функция умеет одновременно складывать до 16 пар чисел. То есть, ей на вход подается два массива по 16 байт, а она выдает один такой же на выход. Вот только делает она это сильно быстрее. Я использовал ее аналог, который складывает 4 пары 4-байтовых чисел и у меня получилось в 2.5 раза быстрее вычисления (да, пришлось немного цикл поправить, чтобы брать числа группами).

Еще ближе к делу. Как это использовать в своем коде. Вначале нужно в include добавить emmintrin.h и все, можно писать код. Вот маленький пример, как просто сложить два числа:

#include #include int main() < unsigned char a[16] __attribute__ ((aligned (16))) = < 200 >; unsigned char b[16] __attribute__ ((aligned (16))) = < 70 >; __m128i l = _mm_load_si128((__m128i*)a); __m128i r = _mm_load_si128((__m128i*)b); __m128i res = _mm_adds_epu8(l, r); _mm_store_si128((__m128i*)a, res); std::cout

А теперь сравните, как складываются 7 чисел:

#include #include int main() < unsigned char a[16] __attribute__ ((aligned (16))) = < 200, 1, 255, 255, 1, 2, 3 >; unsigned char b[16] __attribute__ ((aligned (16))) = < 70, 255, 255, 0, 3, 2, 1>; __m128i l = _mm_load_si128((__m128i*)a); __m128i r = _mm_load_si128((__m128i*)b); __m128i res = _mm_adds_epu8(l, r); _mm_store_si128((__m128i*)a, res); for (int i = 0; i std::cout

Эти два примера компилируются под gcc 4.9.3 и работают как ожидается. Обратите особое внимание на странную конструкцию __attribute__ ((aligned (16))) Это нужно, чтобы адрес массива в памяти был выравнен по адресу, кратному 16. Без этого многие sse функции либо просто не работают, выдавая странные ошибки во время исполнения, либо работают сильно-сильно медленее.

И напоследок код для vs2015. В ней выравнивание для массивов делается немного по другому.

#include #include int main() < __declspec(align(16)) unsigned char a[16] = < 200 >; __declspec(align(16)) unsigned char b[16] = < 70 >; __m128i l = _mm_load_si128((__m128i*)a); __m128i r = _mm_load_si128((__m128i*)b); _mm_store_si128((__m128i*)a, _mm_adds_epu8(l, r)); std::cout

Функция складывает 16 чисел. Но что, если нам нужно сложить только два? Ничего страшного, просто пусть там будет себе мусор, на общую производительность это не влияет. В данном конкретном случае наверно накладные расходы на складывания одного числа могут быть сопоставимы с обычным кодом с if . Но если в цикле складывать по 16 пар чисел, то думаю, что производительность можно поднять в 5-10 раз. Но это уже сильно зависит от окружающего кода.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *