C ++获得整数除法和余数的最佳方法

时间:2011-08-15 20:21:16

标签: c++ division

我只是想知道,如果我想将b除以a,并且对结果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);

也许有一个神奇的功能同时给出一个?

8 个答案:

答案 0 :(得分:86)

在x86上,余数是除法本身的副产品,因此任何半合半的编译器都应该能够使用它(而不是再次执行div)。这可能也是在其他架构上完成的。

  

说明:DIV src

     

注意:未签名的除法。将累加器(AX)除以“src”。如果除数   是一个字节值,结果是AL ,余数是AH 。如果除数   是一个单词值,然后DX:AX除以“src”并存储结果   在AX 中,余数存储在DX

int c = (int)a / b;
int d = a % b; /* Likely uses the result of the division. */

答案 1 :(得分:69)

std::div返回包含结果和余数的结构。

答案 2 :(得分:23)

至少在x86上,g ++ 4.6.1只使用IDIVL并从该单指令中获取。

C ++代码:

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

x86代码:

__Z3fooiiPiS_:
LFB4:
    movq    %rdx, %r8
    movl    %edi, %edx
    movl    %edi, %eax
    sarl    $31, %edx
    idivl   %esi
    movl    %eax, (%r8)
    movl    %edx, (%rcx)
    ret

答案 3 :(得分:9)

示例代码测试div()和组合分区&国防部。我用gcc -O3编译了这些,我不得不添加对doNothing的调用来阻止编译器优化所有内容(对于除法+ mod解决方案,输出将为0)。

带上一粒盐:

#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);
}

输出: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);
}

输出:25

答案 4 :(得分:5)

除上述 std::div 系列函数外,还有 std::remquo 系列函数,返回 rem -ainder并通过传入指针获取 quo -tient。

[编辑:] 毕竟它看起来像std :: remquo doesn't really return the quotient

答案 5 :(得分:3)

在其他条件相同的情况下,最佳解决方案是明确表达您意图的解决方案。所以:

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

可能是您提出的三个选项中最好的。但是,如其他答案中所述,div方法会立即为您计算两个值。

答案 6 :(得分:3)

在32位英特尔平台上,你不能相信g ++ 4.6.3这里有64位整数。通过调用divdi3计算a / b,通过调用moddi3计算%b。我甚至可以想出一个用这些调用来计算a / b和a-b *(a / b)的例子。所以我使用c = a / b和a-b * c。

div方法调用一个计算div结构的函数,但是在具有硬件支持整数类型的平台上(即64位intel / amd平台上的64位整数),函数调用似乎效率低下。

答案 7 :(得分:-4)

您可以使用模数来获得余数。虽然@cnicutar的回答看起来更干净/更直接。