Je me demande simplement, si je veux diviser a par b, et que le résultat c et le reste m'intéressent (par exemple, disons que j'ai le nombre de secondes et que je souhaite scinder cela en minutes et en secondes), quel est le meilleur moyen de aller à ce sujet?
Serait-ce
int c = (int)a / b;
int d = a % b;
ou
int c = (int)a / b;
int d = a - b * c;
ou
double tmp = a / b;
int c = (int)tmp;
int d = (int)(0.5+(tmp-c)*b);
ou
peut-être y a-t-il une fonction magique qui donne les deux à la fois?
Sur x86, le reste est un sous-produit de la division elle-même, donc tout compilateur à la moitié décente devrait pouvoir l'utiliser (et ne pas effectuer à nouveau div
). Ceci est probablement fait sur d'autres architectures aussi.
Instruction:
DIV
srcRemarque: division non signée. Divise l'accumulateur (AX) par "src". Si diviseur est une valeur d'octet, le résultat est mis à AL et le reste à AH. Si diviseur est une valeur Word, alors DX: AXE est divisé par "src" et le résultat est stocké dans AX le reste est stocké dans DX.
int c = (int)a / b;
int d = a % b; /* Likely uses the result of the division. */
std::div
renvoie une structure avec à la fois le résultat et le reste.
Sur au moins x86, g ++ 4.6.1 utilise simplement IDIVL et obtient les deux à partir de cette instruction unique.
Code C++:
void foo(int a, int b, int* c, int* d)
{
*c = a / b;
*d = a % b;
}
code x86:
__Z3fooiiPiS_:
LFB4:
movq %rdx, %r8
movl %edi, %edx
movl %edi, %eax
sarl $31, %edx
idivl %esi
movl %eax, (%r8)
movl %edx, (%rcx)
ret
Exemple de code test div () et division & mod. Je les ai compilés avec gcc -O3, il a fallu ajouter l’appel à doNothing pour empêcher le compilateur d’optimiser l’optimisation totale (le résultat serait 0 pour la solution division + mod).
Prenez-le avec un grain de sel:
#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);
}
Sorties: 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);
}
Sorties: 25
En plus de la famille de fonctions std :: div susmentionnée, il existe également le groupe std :: remquo famille de fonctions, retourne le rem - ainder et récupère le quo - patient via un pointeur passé.
[Edit:] Cela ressemble à std :: remquo ne renvoie pas vraiment le quotient après tout.
Vous ne pouvez pas faire confiance à g ++ 4.6.3 ici avec des entiers 64 bits sur une plate-forme Intel 32 bits. a/b est calculé par un appel à divdi3 et un% b est calculé par un appel à moddi3. Je peux même trouver un exemple qui calcule a/b et a-b * (a/b) avec ces appels. Donc j'utilise c = a/b et a-b * c.
La méthode div appelle une fonction qui calcule la structure div, mais un appel de fonction semble inefficace sur les plates-formes prenant en charge le matériel pour le type intégral (c'est-à-dire des entiers 64 bits sur des plates-formes Intel/AMD 64 bits).
Toutes choses étant égales par ailleurs, la meilleure solution est celle qui exprime clairement votre intention. Alors:
int totalSeconds = 453;
int minutes = totalSeconds / 60;
int remainingSeconds = totalSeconds % 60;
est probablement la meilleure des trois options que vous avez présentées. Comme indiqué dans d'autres réponses cependant, la méthode div
calculera les deux valeurs pour vous en même temps.