Как я могу вычислить это, используя только целочисленные типы данных?

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

a = b / c * d

Где:

0 =< a =< d,

0 =< b =< c,

0 =< c,

0 =< d

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

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

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

a = b / c * d

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

a = b * d / c

—> b*d может привести к переполнению.

Выполните умножение перед делением, используя более крупный шрифт, если будет переполнение. a = (int)((long long)b * d / c); Если вы хотите округлить результат, вы можете добавить (или вычесть, если произведение отрицательное) половину делителя c >> 1 перед делением.   —  person K0ICHI    schedule 07.10.2019

Не могли бы вы указать, какой результат вы хотите. Если a является целым числом, вполне возможно, что оно не может точно хранить результат деления. Вы хотите обрезать? круглый? Вам нужен остаток или можно отказаться от него?   —  person K0ICHI    schedule 07.10.2019

@Флюгер. Большое спасибо, это решение, на которое я надеялся, даже в одной строке кода! Почему бы не сделать это ответом? Я приму. Не могли бы вы также сказать мне, могу ли я считать само собой разумеющимся, что компилятор будет выполнять математику в том же порядке, в котором я его ввел?   —  person K0ICHI    schedule 07.10.2019

Re может считать само собой разумеющимся, что компилятор будет выполнять математические операции в том же порядке, в каком я его ввел. В общем, определенно нет. Но ассоциативность операторов требует, чтобы умножение происходило перед делением, потому что оно слева.   —  person K0ICHI    schedule 07.10.2019

Источник: ledsshop.ru

Стиль жизни - Здоровье!