#c
#c
Вопрос:
В чем разница между следующими двумя?
// uint8_t a; uint8_t b;
uint16_t first = (uint16_t)(a * b);
uint16_t second = (uint16_t)a * (uint16_t)b;
Каковы могут быть варианты использования этих двух видов реализаций?
Комментарии:
1. В обоих случаях операнды повышаются до
int
перед умножением. Итак, если вы работаете на компьютере, гдеint
16-разрядный, первый подход будет выполнять 16-разрядное умножение int со знаком, но не будет способствовать второму случаю, потому что операнды уже будут беззнаковыми. На любом микроконтроллере с 32-разрядными целыми числами вы получите тот же результат.
Ответ №1:
Математическое произведение a*b
находится в диапазоне [0…65,025].
Если unsigned/int
32-разрядный, никакой разницы.
Если unsigned/int
значение 16- a * b
разрядное, int
существует риск переполнения со знаком и неопределенного поведения (UB). Оба a, b
преобразуются int
до умножения и a*b
могут превышать INT_MAX
(32 767).
(uint16_t)a * (uint16_t)b;
лучше.