Как я могу рассчитать это, используя только целочисленные типы данных? - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь запрограммировать следующее в C, используя MPLABX IDE и компилятор XC8, для микроконтроллера PIC12. Раньше я не программировал ни микроконтроллеры, ни C, поэтому есть некоторые новые вещи, которые я должен рассмотреть. Одним из них является то, что вычисления с использованием типов с плавающей запятой неэффективны на этих микроконтроллерах и поэтому их следует избегать. Пытаясь следовать этой философии, я хотел бы узнать лучшую практику для выполнения таких расчетов:

a = b / c * d

Где:

0 =

0 = 0 = 0 =

a, b и c - 16-разрядные целые числа без знака. Можно свободно выбирать d.

Я ищу хороший компромисс между хорошо читаемым исходным кодом и эффективным скомпилированным кодом.

Я рассмотрел вопрос о реструктуризации уравнения, но при исключении одной проблемы возникает другая:

a = b / c * d

-> b / c всегда будет 0. Остаток потерян.

a= b * d / c

-> b * d может вызвать переполнение.

1 Ответ

0 голосов
/ 07 октября 2019

Вы должны выполнить умножение перед делением, используя больший тип, если произойдет переполнение.

a = (int)((long long)b * d / c);

Если у вас есть сомнения относительно последовательности операций, вы можете заключить ее в скобки

a = (int)(((long long)b * d) / c);

хотя это и не нужно, потому что хотя * и / имеют одинаковый приоритет, они анализируются слева направо.

Если вы хотите округлить результат, вы можете добавить (или вычесть, если отрицательный результатпроизведение) половина делителя до деления.

a = (int)(((long long)b * d + (c >> 1)) / c);
...