реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Макрос инкремента с насыщением.
adnega
сообщение Dec 17 2012, 19:32
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(ViKo @ Dec 17 2012, 23:03) *
А вам точно нужно это? Может, лучше - с ограничением?
#define VAR_INC(x, step, max) x = ((x + step)>max)? max : (x + step)

Не пойдет(
Это для каждого счетчика нужно "придумывать" свое ограничение. Причем изменив разрядность (тип) счетчика придется ручками по всему коду править ограничения - а это источник ошибок.
Хотелось на автомате...
Но за неумением "объяснить" свои намеренья оптимизирующему компилятору придется вводить единый тип для всех "тикалок".
Кста, Ваша идея мне нравится и везде я стараюсь пользоваться конструкциями

Код
TICK(timeout);
if(timeout >= TO_TIMEOUT)
{
  state = NEW_STATE;
  timeout = 0;
}


или

Код
if(timeout < TO_TIMEOUT) TICK(timeout);


Что так или иначе ограничивает увеличение timeout, но второй вариант можно использовать только если ограничение какое-то одно (фиксированное), а сам таймер предназначен для ожидания какого-то одного события. Если это не так, то использую вариант 1.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Dec 18 2012, 13:02
Сообщение #17


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(adnega @ Dec 16 2012, 18:37) *
не помогает, в случае знакового x и беззнакового TO_TICK. Видимо, (x + TO_TICK) считается беззнаковым и сравнивается с беззнаковым x.
Конечно, если TO_TICK явно беззнаковое, то в (x + TO_TICK) сначала будет приведение x к беззнаковому.
А зачем TO_TICK беззнаковое? Оно же явно должно влазить по диапазону в знаковые числа, а при (unsignedX + signedTICK) уже тик приведётся к беззнаковому и будет все нормально.
Хотя с битовыми полями и прочими заужениями до байтов все равно будет плохо, так как в + сначала обе стороны приведутся к int и для uint8_t всё равно всегда ((255+1) > 255) истинно и прибавление тика не остановится.

Кстати, с typeof можно и проще
Код
#define TICK(x) do { if ( (typeof(x))(x+TO_TICK) > x ) x += TO_TICK;}while(0)

но с битовыми полями так же не будет работать. Хотя я в таких местах ниже байта не опускаюсь, битовые поля - счётчики немного экономят ОЗУ, но раздувают код (Cortex-M3-шные команді работы с битовыми полями штука хорошая, но не везде есть).

И лучше уж C++ шаблонную функцию, чем такой макрос. Не вижу препятствий работать в процедурном стиле даже без простейших классов, но с такого рода шаблонами. А для кого есть gcc, для того есть и g++.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
adnega
сообщение Dec 20 2012, 10:40
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Цитата(ReAl @ Dec 18 2012, 17:02) *
Конечно, если TO_TICK явно беззнаковое, то в (x + TO_TICK) сначала будет приведение x к беззнаковому.
А зачем TO_TICK беззнаковое? Оно же явно должно влазить по диапазону в знаковые числа, а при (unsignedX + signedTICK) уже тик приведётся к беззнаковому и будет все нормально.

Я-то боюсь, что "умный" оптимизатор вообще вправе выкинуть финт: если к некоторому числу прибавить положительную константу, то результат (чисто в математическом смысле) будет БОЛЬШЕ исходного числа - поэтому условие всегда истинное. А если программисту нужна такая "платформенная вещь" как "переполнение", то либо врукопашную оптимизируй, либо научись грамотно указать оптимизатору свои намеренья.

Вывод для себя делаю такой: если переполняется какая-то переменная, то алгоритм можно считать плохим. На этапе проектирования не нужно допускать неограниченного инкремента "тикающих" переменных (справедливо для всех случаев, кроме измерителя uptime, но тут нужно наращивать разрядность, либо вводить масштаб).

Для битовых полей написать специальный макрос/функцию для выполнения этой конкретной задачи.

Вообще, это скорее проблема программиста (моя), а не инструмента: хочется чтобы программа сама себя писала, но для решения данной проблемы есть ДРУГИЕ инструменты, которыми и нужно пользоваться.
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 20 2012, 11:09
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(adnega @ Dec 20 2012, 14:40) *
Я-то боюсь, что "умный" оптимизатор вообще вправе выкинуть финт: если к некоторому числу прибавить положительную константу, то результат (чисто в математическом смысле) будет БОЛЬШЕ исходного числа - поэтому условие всегда истинное.

Зря боитесь, не будет такого. Компилятор всё делает по стандарту языка Си (с точностью до глюков компилятора, но мы же не о них сейчас говорим). В стандарте четко прописана семантика переполнения целочисленной переменной.

Цитата(adnega @ Dec 20 2012, 14:40) *
Вообще, это скорее проблема программиста (моя), а не инструмента: хочется чтобы программа сама себя писала, но для решения данной проблемы есть ДРУГИЕ инструменты, которыми и нужно пользоваться.

Я с самого начала это хотел сказать. Мне кажется, необходимость насыщения должна возникать редко, поэтому и макрос тут ни к чему.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 20 2012, 12:00
Сообщение #20


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Мне интересно другое. А насыщение в виде равенства нулю? Зачем инкремент, если можно декремент?
Шаманобубен какой-то...
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 19:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.01374 секунд с 7
ELECTRONIX ©2004-2016