Вы не предоставляете некоторые важные детали, но при некоторых разумных допущениях, это 4 и 5, которые разбиты, в то время как 1-3 довольно хорошо.
Я предполагаю, что вы настаиваете на использовании большего промежуточного целочисленного типа, потому что хотите избежать переполнения при сложении. Также не ясно, работаете ли вы со знаковыми типами без знака и почему вы их так смешиваете.
В любом случае, минимальный правильный способ выполнения сложения и сдвига будет
bucket = ((long) ADCBUF0 + ADCBUF7) >> 1;
Переключение на больший тип только одним операндом достаточно. Конечно, вы можете оставить оба броска, если вам нравится более «симметричный» внешний вид.
Или вы можете сделать это вообще без каких-либо приведений (при условии, что bucket
объявлен с «большим» типом)
bucket = ADCBUF0;
bucket = (bucket + ADCBUF7) >> 1;
Что касается окончательного назначения, если получатель сам по себе является unsigned int
(это совершенно неясно из вашего вопроса), нет никакой реальной необходимости в каком-либо приведении, если вы не пытаетесь подавить предупреждения компилятора. Я предполагаю, что это unsigned int
. В этом случае просто
rem_volt = bucket;
будет работать. Если это не unsigned int
, то явное приведение может иметь значение, но невозможно сказать, пока вы не предоставите эту важную деталь.
Неважно, где вы делаете сдвиг в вашем случае (в первом или во втором утверждении), опять же, если bucket
имеет тип "больше". Если bucket
объявлен с тем же типом, что и переменные ADC...
, то сдвиг должен быть сделан рано (в первом выражении).
Что касается ваших вариантов: 1 в порядке, но второе приведение является технически избыточным (вопрос стиля). 2 в порядке, с двумя чрезмерными забросами. 3 также в порядке, с чрезмерным броском. 4 не работает, поскольку он не защищает от переполнения (если это было вашим намерением). 5 сломан таким же образом.
Другими словами, из всех ваших вариантов номер 1 выглядит лучше (опять же, предполагая, что приведение к unsigned int
избыточно).
P.S. Если вы хотите разделить что-то на 2, самый разумный способ сделать это - использовать оператор деления /
и константу 2
в качестве делителя. Нет смысла вносить какие-либо изменения в картину.
Кроме того, Мэтью Слэттери в своем ответе предоставил не переполненный способ вычисления среднего значения с использованием операций переворота битов. Это также может быть сделано другим (возможно, более читабельным) способом через
average = ADCBUF0 / 2 + ADCBUF7 / 2 + (ADCBUF0 % 2 & ADCBUF7 % 2);
или, если вы предпочитаете подход с битовой перестановкой
average = (ADCBUF0 >> 1) + (ADCBUF7 >> 1) + (ADCBUF0 & ADCBUF7 & 1);