Приведение типов в C для каждой из переменных

#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; лучше.