Разница между "Math.DivRem" и% оператором?
В чем разница между System.Math.DivRem()
и оператором %
?
Ответы
Ответ 1
%
дает вам остальную часть деления и полностью отбрасывает значение, а DivRem()
вычисляет и возвращает как фактор, так и остаток.
Если вас беспокоит остальная часть деления между двумя целыми числами, используйте %
:
int remainder = 10 % 3;
Console.WriteLine(remainder); // 1
Если вам нужно знать, сколько раз 10 было разделено на 3, прежде чем осталось 1, используйте DivRem()
, который возвращает фактор и сохраняет остаток в выходном параметре:
int quotient, remainder;
quotient = Math.DivRem(10, 3, out remainder);
Console.WriteLine(quotient); // 3
Console.WriteLine(remainder); // 1
Ответ 2
Это оптимизация. Некоторые процессоры могут одновременно вычислять оба значения. Другие процессоры не могут разделить аппаратное обеспечение (и должны использовать, очень медленно, программные подпрограммы).
В любом случае (если у вас нет интеллектуального компилятора) вы можете в конечном итоге вычислить одно и то же подразделение дважды. Поскольку деления никогда не бывают быстрыми, на любом процессоре (даже если они реализованы в аппаратном обеспечении), то использование Math.DivRem дает JIT хороший "подсказку" для вычисления значений только один раз.
iirc Моно не реализует эту оптимизацию, и я даже не уверен, что MS делает.
Ответ 3
Возможно, это была оптимизация, но, к сожалению, производит тот же IL-код, что и операция разделения PLUS.
В типичных архитектурах (x86 и друзьях) два могут быть получены из одной операции, но .NET JIT, похоже, не оптимизирует это (в моих тестах).
Итак, следующие два эквивалентны:
quotient = Math.DivRem(10, 3, out remainder);
VS:
quotient = 10 / 3;
remainder = 10 % 3;
Кроме того, более поздняя версия более читаема.
Для записи эта уродливая опция выполняется быстрее на x86 и x64:
quotient = 10 / 3;
remainder = 10 - (3*quotient);
Надеюсь, JIT улучшится в один прекрасный день, чтобы оптимизировать две операции в одну, поскольку это тривиально.