Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: как правильно умножить 16 на 16 бит?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
Александр Куличок
При умножении 2х 16-тных переменных
Код
void main(void)
{
  volatile int a = 200;
  volatile  int b = 300;
  volatile long c = a*b;
}


AVR IAR (v5.11B) сначала делает умножение 16*16=16 бит и только после этого расширяет результат до 32х бит. При чем если оба операнда типа int, расширение до 32х бит осуществляется со знаком. А если хотя бы один из них - unsigned - то в 16 старших бит просто дописываются 00.

Поэтому возник вопрос - как "правильно " сделать умножение без обрезки результата?

Подозреваю, что это вполне корректное поведение С-компилятора, которое обусловлено какими-то стандартами. Поэтому хотелось бы еще и узнать, где можно доступно почитать об подобных особенностях компиляторов. И одинаковы ли данные особенности под 8-ми, 16-ти и 32-двухбитные платформы.
rezident
Цитата(Александр Куличок @ Dec 20 2008, 03:04) *
Поэтому возник вопрос - как "правильно " сделать умножение без обрезки результата?

Например, так (явное приведение типа)
Код
void main(void)
{
  volatile int a = 200;
  volatile  int b = 300;
  volatile long c = (long)a*b;
}


Цитата(Александр Куличок @ Dec 20 2008, 03:04) *
Подозреваю, что это вполне корректное поведение С-компилятора, которое обусловлено какими-то стандартами. Поэтому хотелось бы еще и узнать, где можно доступно почитать об подобных особенностях компиляторов. И одинаковы ли данные особенности под 8-ми, 16-ти и 32-двухбитные платформы.
Читайте стандарты ANSI C и C99.
scifi
Цитата(Александр Куличок @ Dec 20 2008, 01:04) *
Поэтому возник вопрос - как "правильно " сделать умножение без обрезки результата?

Можно так:
Код
int a, b;
long c = (long)a * (long)b;

Или так:
Код
int a, b;
long c = (long)a * b;

Второй вариант эквивалентен первому благодаря автоматическому приведению целочисленного типа. Второй вариант также короче, но в нём меньше симметрии...
Александр Куличок
to resident: спасибо за ссылку (и ответ).

То есть выражение типа с = a * b + k * m , где все переменные справа - 16-битные, превращается в
с = (long)a * (long)b + (long)k * (long)m ?
как-то не очень красиво выглядит.
Nixon
второй и четвертый long - лишние
Baser
Цитата(Александр Куличок @ Dec 20 2008, 00:04) *
Подозреваю, что это вполне корректное поведение С-компилятора, которое обусловлено какими-то стандартами. Поэтому хотелось бы еще и узнать, где можно доступно почитать об подобных особенностях компиляторов. И одинаковы ли данные особенности под 8-ми, 16-ти и 32-двухбитные платформы.

Кроме стандартов на "аглицком" можно и на русском справочники почитать.
Эти книги у меня всё время под рукой, периодически заглядываю, ибо всё помнить нельзя...
Вот одна от отцов-основателей:
Брайан Керниган, Деннис Ритчи: Язык программирования C (второе издание)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.