|
Макрос инкремента с насыщением. |
|
|
|
Dec 16 2012, 16:37
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Имеем gcc, пишем на C. Задача: нужно написать некоторый макрос TICK(x), который бы при каждом вызове увеличивал переменную x на константу TO_TICK, но с учетом переполнения. Т.е. в случае если добавление TO_TICK вызовет переполнение, переменную x не изменять. Тип переменной x может быть любой целый (в том числе битовое поле). Вариант 1: Код #define TICK(x) do{if((x + TO_TICK) > x) x += TO_TICK;}while(0) не помогает, в случае знакового x и беззнакового TO_TICK. Видимо, (x + TO_TICK) считается беззнаковым и сравнивается с беззнаковым x. Вариант 2: Код #define TICK2(x) do{typedef typeof(x) _tx; _tx _x = x; _x += TO_TICK; if(_x > x) x = _x;}while(0) в принципе устраивает, но не работает с битовыми полями. Параллельно узнал, что char без указания знаковости в "gcc version 4.8.0 20121121 (experimental) (Klen's GNU package (KGP) for ARM/elf platform)" является unsigned, хотя везде указывается диапазон char от -128 до 127. В "gcc версия 4.4.3 (GCC)" под Linux char знаковый. Где нужно читать о типах данных C/GCC и приведении типов в арифметических операциях и операциях сравнения? Кстати, при различных уровнях оптимизации результат тоже получаю различный. Хочется большей строгости... Спасет ли переход на C++/GCC ?
|
|
|
|
|
 |
Ответов
|
Dec 16 2012, 16:59
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Код #define TICK(x) do{ unsigned char a = x+TO_TICK; if(a > TO_TICK) x=a;}while(0); и вообще, какого икса дефайнить? Код static inline Tick(unsigned char *x) { unsigned char a = *x+TO_TICK; if(a > TO_TICK) *x=a; }
Сообщение отредактировал _Pasha - Dec 16 2012, 17:03
|
|
|
|
|
Dec 16 2012, 18:29
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(_Pasha @ Dec 16 2012, 22:26)  Во! А теперь еще более интересный вопрос: у Вас "тикающий тип" - это одна сущность или много? Вернее, почему нельзя создать тип нужной размерности, скажем typedef unsigned int tick_t Если на то есть причины, расскажите, плз, очень интересно. А то! Раньше было много, сейчас, видимо, придется переходить на одну. В целях экономии памяти использую различную разрядность "тикающих типов", в идеале вплоть до битовых полей.
|
|
|
|
Сообщений в этой теме
adnega Макрос инкремента с насыщением. Dec 16 2012, 16:37 adnega Цитата(adnega @ Dec 16 2012, 20:37) Вариа... Dec 16 2012, 18:52 _Артём_ Цитата(adnega @ Dec 16 2012, 20:52) Сдела... Dec 16 2012, 19:09 adnega Цитата(adnega @ Dec 16 2012, 22:52) Не ра... Dec 16 2012, 19:14  _Артём_ Цитата(adnega @ Dec 16 2012, 21:14) Потом... Dec 16 2012, 19:21 _Pasha Попутно еще замечание, что параметр функции const ... Dec 16 2012, 20:33 polyname может лучше сравнивать с разностью ?
Код#define AD... Dec 17 2012, 06:11 andrew_b Цитата(adnega @ Dec 16 2012, 20:37) Парал... Dec 17 2012, 06:55 ARV #define TICK(x) x = ((x) + TO_TICK) < (x) ? (x)... Dec 17 2012, 18:35 ViKo Цитата(adnega @ Dec 16 2012, 19:37) Задач... Dec 17 2012, 19:03 adnega Цитата(ViKo @ Dec 17 2012, 23:03) А вам т... Dec 17 2012, 19:32 ReAl Цитата(adnega @ Dec 16 2012, 18:37) не по... Dec 18 2012, 13:02 adnega Цитата(ReAl @ Dec 18 2012, 17:02) Конечно... Dec 20 2012, 10:40  scifi Цитата(adnega @ Dec 20 2012, 14:40) Я-то ... Dec 20 2012, 11:09 _Pasha Мне интересно другое. А насыщение в виде равенства... Dec 20 2012, 12:00
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|