Мне просто интересно, если я хочу разделить a на b и меня интересует как результат c, так и остаток (например, скажем, у меня есть количество секунд и я хочу разделить его на минуты и секунды), каков наилучший способ пойти об этом?
Будет ли это
int c = (int)a / b;
int d = a % b;
или
int c = (int)a / b;
int d = a - b * c;
или
double tmp = a / b;
int c = (int)tmp;
int d = (int)(0.5+(tmp-c)*b);
или
может быть, есть волшебная функция, которая дает и то, и другое одновременно?
double
(вашим последним элементом) кажется мне плохой идеей, вы получите числа, которые не совпадают и могут стоить вам производительности и размер исполняемого файла (всегда был проблемой для некоторых встроенных систем).Ответы:
На x86 остаток является побочным продуктом самого подразделения, поэтому любой полуприличный компилятор должен иметь возможность просто использовать его (и не выполнять
div
снова). Вероятно, это сделано и на других архитектурах.источник
idivl
инструкции и с использованием результатов в eax и edx. Если бы это было не так, я был бы шокирован.idivl
инструкции, но с-O1
или выше вы получаете одну. Как сказано в руководстве: «Без какой-либо возможности оптимизации… Заявления независимы» .std::div
возвращает структуру с результатом и остатком.источник
long long
, но весьма вероятно, что ваш компилятор имеетlong long
перегрузкуstd::div
в качестве расширения.По крайней мере, на x86 g ++ 4.6.1 просто использует IDIVL и получает и то, и другое из этой единственной инструкции.
Код на C ++:
x86 код:
источник
/=
- вам может потребоваться временная переменная, чтобы сначала сохранить деление.Пример кода тестирования div () и комбинированного деления и мода. Я скомпилировал их с помощью gcc -O3, мне пришлось добавить вызов doNothing, чтобы остановить компилятор от оптимизации всего (вывод будет 0 для решения с делением + мод).
Отнеситесь к этому с недоверием:
Выходы: 150
Выходы: 25
источник
В дополнение к вышеупомянутому станду :: сНа семейству функций, есть также станд :: remquo семейство функций, возвращают бэры -ainder и получение кво -tient через сдавшую в указателе.
[Edit:] Похоже, что std :: remquo на самом деле не возвращает частное .
источник
При прочих равных, лучшее решение - это то, которое четко выражает ваши намерения. Так:
вероятно, лучший из трех представленных вами вариантов. Однако, как отмечено в других ответах, этот
div
метод вычислит для вас оба значения одновременно.источник
Здесь нельзя доверять g ++ 4.6.3 с 64-битными целыми числами на 32-битной платформе Intel. a / b вычисляется вызовом divdi3, а a% b вычисляется вызовом moddi3. Я даже могу привести пример, который вычисляет a / b и ab * (a / b) с этими вызовами. Поэтому я использую c = a / b и ab * c.
Метод div вызывает функцию, которая вычисляет структуру div, но вызов функции кажется неэффективным на платформах, которые имеют аппаратную поддержку интегрального типа (т.е. 64-битные целые числа на 64-битных платформах Intel / AMD).
источник
Вы можете использовать модуль, чтобы получить остаток. Хотя ответ @cnicutar кажется более чистым / прямым.
источник