128

I am just wondering, if I want to divide a by b, and am interested both in the result c and the remainder (e.g. say I have number of seconds and want to split that into minutes and seconds), what is the best way to go about it?

Would it be

int c = (int)a / b;
int d = a % b;

or

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

or

double tmp = a / b;
int c = (int)tmp;
int d = (int)(0.5+(tmp-c)*b);

or

maybe there is a magical function that gives one both at once?

Cookie
  • 12,004
  • 13
  • 54
  • 83
  • 6
    all the answers below seem reasonable, I would just like to add that any mucking with `double` (your last item) seems to me like a bad idea, you will end up with numbers that don't line up, and can cost you in performance and executable size (was always an issue for me on certain embedded systems). – nhed Aug 15 '11 at 20:36
  • 2
    The third is a BAD option: what if tmp = 54.999999999999943157? This said, old style casting is never a clever thing to do. – jimifiki Jul 15 '14 at 13:05

9 Answers9

128

On x86 the remainder is a by-product of the division itself so any half-decent compiler should be able to just use it (and not perform a div again). This is probably done on other architectures too.

Instruction: DIV src

Note: Unsigned division. Divides accumulator (AX) by "src". If divisor is a byte value, result is put to AL and remainder to AH. If divisor is a word value, then DX:AX is divided by "src" and result is stored in AX and remainder is stored in DX.

int c = (int)a / b;
int d = a % b; /* Likely uses the result of the division. */
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 14
    I think many poeple know from elementary school that when doing a division you get the remainder for free. The real question is: are our compilers smart enough to take advantage of this? –  Aug 15 '11 at 20:32
  • Agree - But if b is a power of 2 you could use bit shift. – Ed Heal Aug 15 '11 at 20:34
  • 1
    @jdv: I wouldn't be surprised. It's a very simple optimisation. – Jon Purdy Aug 15 '11 at 20:38
  • 85
    I tried a quick test. With g++ 4.3.2 using -O2, the assembler output clearly shows it using one `idivl` instruction and using the results in eax and edx. I'd have been shocked if it didn't. – Fred Larson Aug 15 '11 at 20:41
  • Strangely this does not appear to be the case in .Net languages; presumably because of some oddball detail of .Net itself, rather than because of something simple like not running with optimizations enabled. – Chris Moschini Jul 27 '14 at 20:38
  • .Net has System.Math.DivRem which returns quitient and remainder. Not done any benchmarks thought. – Archy Nov 02 '16 at 08:51
  • This is not question about x86, I wonder why it is an accepted answer. – Euri Pinhollow Aug 08 '17 at 12:49
  • 2
    @EuriPinhollow Agree this is not a question about x86. I only gave it as an example, with the highly dubious assumption that other architectures probably do something similar. – cnicutar Aug 08 '17 at 14:28
  • 4
    You do need to tell the compiler to optimize, though, at least for g++. A simple experiment with g++ 6.3.0 on x86_64 revealed that with no optimization at all, you get two `idivl` instructions, but with `-O1` or greater, you get one. As the manual says, [“Without any optimization option … Statements are independent”](https://gcc.gnu.org/onlinedocs/gcc-6.4.0/gcc/Optimize-Options.html). – Tom Zych Oct 15 '17 at 05:28
  • Is (int) the correct way to do a cast in C++? I ask it because someone, in another question, said me that I'm doing C casting in C++ code. Thanks. – VansFannel Apr 03 '21 at 06:45
  • Does this also apply to other architectures such as ARM and RISC-V? – Aaron Franke May 25 '21 at 08:09
115

std::div returns a structure with both result and remainder.

pezcode
  • 5,490
  • 2
  • 24
  • 37
  • 5
    I'm curious to know if this is actually more efficient than, say, option 1 on a modern compiler. – Greg Howell Aug 15 '11 at 20:27
  • 2
    Nice, i did not know. Is it faster? –  Aug 15 '11 at 20:27
  • Nice. Would you happen to know if one is implemented for long long somewhere? – Cookie Aug 15 '11 at 20:39
  • @Cookie : C++03 has no concept of `long long`, but it's highly likely that your compiler has a `long long` overload of `std::div` as an extension. – ildjarn Aug 15 '11 at 20:40
  • @Greg: I don't think it is, given that it most likely has to write results to a structure in memory and return it, which (unless it compiles as inline and the struct access is optimized away) is a bigger penalty than doing an extra division instruction. – pezcode Aug 15 '11 at 20:42
  • @GregHowell I would _assume_ it compiles down to the same thing in C++11, seeing as it seems to be defined in terms of them. However, I haven't actually checked. – Nic Jul 05 '18 at 06:52
  • 4
    It looks efficient. cppreference says that following "On many platforms, a single CPU instruction obtains both the quotient and the remainder, and this function may leverage that, although compilers are generally able to merge nearby / and % where suitable. " – Dilawar Nov 26 '19 at 06:07
  • 6
    I don't care if it's faster. *It's more readable*. Using both `/` and `%`, you will have code duplication or extra variables for divisor and dividend, and inexperienced readers may ask: will this be optimized? `std::div` is more clear, reduces ambiguity and redundancy. With structured bindings, it is very elegant to use: `const auto [q, r] = std::div(divisor, dividend);` – pasbi Nov 28 '20 at 10:11
  • 1
    @pasbi the documentation specifically rules out assuming a particular memory order for the quotient and remainder. – William Cushing May 06 '22 at 20:58
  • @pasbi I must disagree. Introducing a `std::div` call instead of using the most obvious (first that comes to mind) approach is the opposite of readable. Almost anyone can see the 2-variable div and remainder approach and know exactly what is going on without having to think twice, even people from other languages, e.g. Java, JS, etc. Newbies will likely be questioning your bracketed syntax, and will need to take a look at std::div's docs, wondering if there was something "special" that warranted its use over the other approach. However I do agree that it's more elegant. – Kröw Mar 05 '23 at 04:50
36

On x86 at least, g++ 4.6.1 just uses IDIVL and gets both from that single instruction.

C++ code:

void foo(int a, int b, int* c, int* d)
{
  *c = a / b;
  *d = a % b;
}

x86 code:

__Z3fooiiPiS_:
LFB4:
    movq    %rdx, %r8
    movl    %edi, %edx
    movl    %edi, %eax
    sarl    $31, %edx
    idivl   %esi
    movl    %eax, (%r8)
    movl    %edx, (%rcx)
    ret
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • Does the order matter? For example if you are iterating over a `/=` - you might need to use a temporary variable to keep division first. – AnnanFay Dec 08 '16 at 15:15
  • @Annan It didn't matter back then, and it doesn't nowadays. Compilers are smart enough to reorder it. –  Dec 05 '19 at 21:41
12

Sample code testing div() and combined division & mod. I compiled these with gcc -O3, I had to add the call to doNothing to stop the compiler from optimising everything out (output would be 0 for the division + mod solution).

Take it with a grain of salt:

#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>

extern doNothing(int,int); // Empty function in another compilation unit

int main() {
    int i;
    struct timeval timeval;
    struct timeval timeval2;
    div_t result;
    gettimeofday(&timeval,NULL);
    for (i = 0; i < 1000; ++i) {
        result = div(i,3);
        doNothing(result.quot,result.rem);
    }
    gettimeofday(&timeval2,NULL);
    printf("%d",timeval2.tv_usec - timeval.tv_usec);
}

Outputs: 150

#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>

extern doNothing(int,int); // Empty function in another compilation unit

int main() {
    int i;
    struct timeval timeval;
    struct timeval timeval2;
    int dividend;
    int rem;
    gettimeofday(&timeval,NULL);
    for (i = 0; i < 1000; ++i) {
        dividend = i / 3;
        rem = i % 3;
        doNothing(dividend,rem);
    }
    gettimeofday(&timeval2,NULL);
    printf("%d",timeval2.tv_usec - timeval.tv_usec);
}

Outputs: 25

Greg Howell
  • 1,885
  • 1
  • 12
  • 13
7

In addition to the aforementioned std::div family of functions, there is also the std::remquo family of functions, return the rem-ainder and getting the quo-tient via a passed-in pointer.

[Edit:] It looks like std::remquo doesn't really return the quotient after all.

Community
  • 1
  • 1
Jamin Grey
  • 10,151
  • 6
  • 39
  • 52
4

You cannot trust g++ 4.6.3 here with 64 bit integers on a 32 bit intel platform. a/b is computed by a call to divdi3 and a%b is computed by a call to moddi3. I can even come up with an example that computes a/b and a-b*(a/b) with these calls. So I use c=a/b and a-b*c.

The div method gives a call to a function which computes the div structure, but a function call seems inefficient on platforms which have hardware support for the integral type (i.e. 64 bit integers on 64 bit intel/amd platforms).

brac37
  • 61
  • 1
4

All else being equal, the best solution is one that clearly expresses your intent. So:

int totalSeconds = 453;
int minutes = totalSeconds / 60;
int remainingSeconds = totalSeconds % 60;

is probably the best of the three options you presented. As noted in other answers however, the div method will calculate both values for you at once.

Jon
  • 3,065
  • 1
  • 19
  • 29
0

Many answers suggest using the following code:

int div = a / b;
int mod = a % b;

However, it is worth remembering that division, unlike multiplication, addition is performed much longer (as far as I know, dozens of times of clock cycles compared to one). And, if you need to repeatedly calculate mod and div, then it is worth replacing two divisions with one division, one multiplication and one addition as follows:

int div = a / b;
int mod = a - div * b;
Alexey Ismagilov
  • 187
  • 2
  • 11
-5

You can use a modulus to get the remainder. Though @cnicutar's answer seems cleaner/more direct.

Sinthet
  • 873
  • 2
  • 8
  • 13