Pull to refresh

Comments 15

С наскока не осилил — малость сумбурно написано. Но тема очень заинтересовала, добавил в избранное, буду на досуге курить. Спасибо.
Да, Вы правы, несколько скомкано, очень трудно перенести разговор (лекцию) на бумагу.
Прежде чем начнешь думать о таких вещах, нужно лет 10 попрограммировать :))
35 лет программирую но задумываться над этим я стал лет 5 назад )

Программирую 5 лет. Осознал в первый день работы с МК.

Использовать начал, конечно, давно. Задумываться начал о том, почему именно так сделано, и можно ли иначе сделать.
Ну или берем переменную на пару байт больше.
оффтоп
Смотрю на сравнение image
image
И не могу вспомнить что же мне напоминает такая строчная I с засечками… И вспоминаю basic, а I это же счетчик с который чаще всего в сравнениях.

Вся статья о


Oldtime = time;
time += deltatime;
if(Oldtime < time) overlaps = true;
return deltatime;

Просто не надо использовать time - oldtime, а использовать для этого готовые модули.

Спасибо, вспомнил про преобразование к int для более коротких типов. Я праввильно понимаю, что для 32битного процессора


uin8_t T, П;
//...
if ( (T-П) & (1u << 8) )

будет эквивалентно, но предупреждения от MISRA не вызовет?
Ещё не подскажете, как на строку


if ( (c = uc ) == uc) printf ( "is equal");

реагируют статические анализаторы и не меняется ли она при разных уровнях оптимизации?

делал несколько прощее/глупее (нужное выбрать по вкусу :) )
исходил из того что практически любой main() представляет собой программное колесо сансары, т.е. пустой цикл прокатывающий один и тот же путь задач.
так вот таймер был аппаратный и в конце цикла просто обнулялся, так что любые интервальные вычисления внутри цикла были элементарны, а после более-менее устаканившегося набора задач еще пополнился watchdogом с двухкратным запасом.
дата и время жили отдельно и использовались для мухлеваний с более длинными интервалами.
Часть из кучи абзацев про проблемы с «Т — П >= 0» можно было изложить намного короче.
По факту мы выбираем такое множество значений Т, которое будет считаться за «интервал истёк».

В случае с беззнаковым «Т — С >= И» это все числа, кроме [С… С+И) (диапазон с учётом возможного перехода с Max на 0 в середние).
В случае с знаковым «Т-П>=0» это числа [С+И… С+И+HalfMax) или (чтобы удобнее было сравнивать с первым случаем) все числа, кроме [С+И-HalfMAx… С+И), где HalfMax — число с единицей в старшем разряде и нулями в остальным, 128 для 8 бит, 32768 для 16 итд

Ну и надо выбрать, какой вариант вам больше подходит, первый — определённо надёжнее, так как не захватывает лишний хвост Т<С, второй — проще в реализации и совсем чуть-чуть быстрее.
Дело в том, что когда мы перешли от С и И к П, мы потеряли часть информации, причем необратимо.
Поэтому привлекать И мы уже не можем, вот и приходится искать новый (надуманный) критерий — половина максимального.
Что за хрень? Все время приводится к ближайшему беззнаковому целому и дальше можно наплевать на переполнения.

uint32_t С;
uint32_t И;
uint32_t Т;

if ((uint32_t)(Т-С) > И)
Fire();
> мы теперь не можем заказать интервал более половины максимально возможного числа, вернее, заказать можем, но он прекратится мгновенно, так что Вам решать, стоит ли выигрыш подобного ограничения. В Linux системах принят именно последний вариант

Ну это по крайней мере логично. Легче поднять этот интервал, чем бороться с эффектами на краю переполнения.

> А надо использовать MISRA и вообще не напрягаться

А можете сформулировать, что тут говорит MISRA?
MISRA явно запрещает сложные выражения с беззнаковыми числами и не дает нам выстрелить в ногу.
10.1 The value of an expression of integer type shall not be implicity converted to a different underlying type if:

(b) the expression is complex
Sign up to leave a comment.

Articles