Как ограничить значение переменной в data class-е?
Как сделать так, чтобы int status из HistoryItem мог быть установлен только на значение из Statuses?
- Вопрос задан более двух лет назад
- 82 просмотра
Комментировать
Решения вопроса 1
Java, Kotlin, Android Developer
Использвать enum вместо инта.
Вроде последняя версия room умеет автоматом работать с enum. Если нет, можно написать адаптер.
Ответ написан более двух лет назад
Комментировать
Нравится 1 Комментировать
Ответы на вопрос 0
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- 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 раз. Но это уже сильно зависит от окружающего кода.