Когда используете знаковые целые (int32_t, например), не
используйте сдвиги. Просто пишите *256 или /256. Иначе нарвётесь на
знак, рано или поздно. Сдвиг со знаком без специальных мер не
работает. А компилятор достаточно умён, чтобы заменить 256 на
сдвиги с должным учётом знака. Насчёт нелинейности... Хмм... Такой подход приближает к экспоненциальному фильтру, который предложили первым. Будет хорошо работать только если амплитуда помехи не достигает 2^4 единиц кода АЦП. В противном случае, помеха будет фильтроваться в разы хуже. И да, тут тоже замените сдвиги на /16.