Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Можно ли в WinAVR обозначить максимальное беззнаковое число как нибудь однообразно для переменных разного размера?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Laksus
Можно ли в WinAVR обозначить максимальное беззнаковое число как нибудь однообразно для переменных разного размера?
Например если
Код
uint8_t      cnt1;
uint16_t     cnt2;
uint32_t     cnt3;

то можно ли вместо
Код
if(cnt1 < 0xFF) cnt1++;
if(cnt2 < 0xFFFF) cnt2++;
if(cnt3 < 0xFFFFFFFF) cnt3++;

написать, что-то вроде
Код
if(cnt1 < MAX(cnt1)) cnt1++;
if(cnt2 < MAX(cnt2)) cnt2++;
if(cnt3 < MAX(cnt3)) cnt3++;

Вообще то, конечно, можно и 0xFFFF обойтись, но по-моему если бы было однообразно, то меньше шансов случайно ошибиться с разрядностью.

ae_
Может вот так?
Код
if(!(++cnt1)) cnt1--;
if(!(++cnt2)) cnt2--;
if(!(++cnt3)) cnt3--;
sensor_ua
или другими словами
Код
if (cnt1+1) cnt1++;
prottoss
Цитата(sensor_ua @ Jan 23 2011, 13:11) *
или другими словами
Код
if (cnt1+1) cnt1++;
Может топикстартеру это подойдет, но этот код будет выполнятся медленнее чем тот, что показал топикстартер
rezident
А не проще ли так?
Код
if(cnt1 < (uint8_t)(-1)) cnt1++;
if(cnt2 < (uint16_t)(-1)) cnt2++;
if(cnt3 < (uint32_t)(-1)) cnt3++;
ReAl
Именно в avr-gcc ?
Тогда, на скорую руку и без проверки, не подсунули ли переменную со знаком, так;
Код
#include <stdint.h>

#define MAX(a) ((__typeof(a))-1)

uint8_t  cnt1;
uint16_t cnt2;
uint32_t cnt3;

void foo() {
        if( cnt1 < MAX(cnt1) ) ++cnt1;
        if( cnt2 < MAX(cnt2) ) ++cnt2;
        if( cnt3 < MAX(cnt3) ) ++cnt3;
}
SlavaG
А можно ещё так попробовать
Код
#define MAX(v) ((1<<(sizeof(v)*8))-1)
777777
Цитата(prottoss @ Jan 23 2011, 10:23) *
Может топикстартеру это подойдет, но этот код будет выполнятся медленнее чем тот, что показал топикстартер

Не факт, что этот код даст то, что нужно: при выполнении операций переменные приводятся к типу int
sensor_ua
Цитата
Не факт, что этот код даст то, что нужно: при выполнении операций переменные приводятся к типу int
Возможно, Вы правы и дополнение будет применено не к результату, а к операндам под-if-ного выражения. Лень стандарт поднимать - если вторые скобки добавить, то как? (не насчёт скорости, а насчёт результата)
Laksus
Спасибо всем ответившим, и особое спасибо ReAl.
Насколько я понял вроде бы дает код точно такой как и с разными 0xFF..., вроде бы само подставляет нужное количество разрядов. По-моему это то, что я хотел.
(Проверка на знак не нужна, только на размер, только WinAVR.)

Остальные способы по-моему не совсем то что мне нужно.
___
И еще вопрос в продолжение этой темы.
А как кто в своих реальных программах проверяет не переполнился ли счетчик.
А то может это я пытаюсь велосипед изобрести, а есть какие то устоявшиеся "стандартные" методы.

PS
Насчет "Остальные способы по-моему не совсем то что мне нужно." возможно я неправ.
#define MAX(v) ((1<<(sizeof(v)*8))-1) пока не пробовал.
sensor_ua
Цитата
А как кто в своих реальных программах проверяет не переполнился ли счетчик.

Чаще употребляю обратный отсчёт. Тогда
Код
if (count) count--;

В таком случае можно сделать принятие решения об окончании отсчета для переменной бОльшего размера, чем разрядность камня, без запрещения прерываний - проверяем по-байтно сначала старший байт - если ноль, то следующий младше и т.д. Обычно у мну для этого намалёваны макросы COUNTDOWN16(X) и COUNTDOWN32(X).

Для расчёта задержек при "мягком риалтайме" использую разницу беззнаковых целых.
Код
clock_t clock(void);
clock_t clock_Elapsed(clock_t ts){
  clock_t tc = clock();
  return (tc - ts);
}
void pause(clock_t duration){
  clock_t ts = clock();
  while(clock_Elapsed(ts) < duration){;}
}

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.