Difference between "Math.DivRem" and % operator?

16,027

Solution 1

% gives you the remainder of a division and discards the quotient altogether, while DivRem() calculates and returns both the quotient and the remainder.

If you're only concerned about the remainder of a division between two integers, use %:

int remainder = 10 % 3;
Console.WriteLine(remainder); // 1

If you need to know how many times 10 was divided by 3 before having a remainder of 1, use DivRem(), which returns the quotient and stores the remainder in an out parameter:

int quotient, remainder;
quotient = Math.DivRem(10, 3, out remainder);
Console.WriteLine(quotient);  // 3
Console.WriteLine(remainder); // 1

Solution 2

It is an optimization. Some processors are able to compute both values at the same time. Other processors can't divide in hardware (and must use, very slow, software routines).

In either case (unless you have a smart compiler) you can end up computing the same division twice. Since divisions are never fast, on any processor (even when implemented in hardware), then using Math.DivRem gives the JIT a nice 'hint' to compute the values only once.

iirc Mono does not implement this optimization, and I'm not even sure if MS does.

Solution 3

It could have been an optimization, but unfortunately produces the same IL as a division PLUS a mod operation.

On typical architectures (x86 & friends) the two can be obtained from a single operation, but .NET JIT seems not to optimize that (in my tests).

So the following two are equivalent:

quotient = Math.DivRem(10, 3, out remainder);

VS:

quotient  = 10 / 3;
remainder = 10 % 3;

Except the later is more readable.

For the record this ugly option is faster on x86 & x64:

quotient  = 10 / 3;
remainder = 10 - (3*quotient);

Hopefully the JIT will improve some day to optimize the two operations into a single one, since it is trivial.

Share:
16,027

Related videos on Youtube

mbrownnyc
Author by

mbrownnyc

(my about me is currently blank)

Updated on June 15, 2022

Comments

  • mbrownnyc
    mbrownnyc almost 2 years

    What is the difference between System.Math.DivRem() and the % operator?

  • BoltClock
    BoltClock over 12 years
    If you only need the quotient of two integers, you can simply do integer division using the / operator instead of %: int quotient = 10 / 3;
  • BoltClock
    BoltClock over 12 years
    And in VB.NET the integer division operator is \: Dim quotient As Integer = 10 \ 3
  • mbrownnyc
    mbrownnyc over 12 years
    Thanks for explaining the underlying processes. I am coding in c#, and obviously using .NET framework; but it's very good to expand. Hey... I just finished reading this: infoworld.com/print/169171
  • mbrownnyc
    mbrownnyc over 12 years
    Thanks guys. I may actually work with Decimal.Divide() since I do not want an whole integer returned.
  • ToolmakerSteve
    ToolmakerSteve about 7 years
    @mbrownnyc re "I do not want a whole integer returned": convert either or both values to a non-integer type before dividing: double result = a / (double)b; That is the non-integer result of a division of two integers.