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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7070346/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:26:09  来源:igfitidea点击:

C++ Best way to get integer division and remainder

c++division

提问by Cookie

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?

我只是想知道,如果我想将 a 除以 b,并且对结果 c 和余数都感兴趣(例如说我有秒数并想将其分成分钟和秒),最好的方法是什么去做吗?

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?

也许有一种神奇的功能可以同时提供两者?

采纳答案by cnicutar

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 divagain). This is probably done on other architectures too.

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

Instruction: DIVsrc

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.

说明:DIVsrc

注:无符号除法。将累加器 (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. */

回答by pezcode

std::divreturns a structure with both result and remainder.

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

回答by Peter Alexander

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

至少在 x86 上,g++ 4.6.1 只使用 IDIVL 并从那条指令中获取两者。

C++ code:

C++代码:

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

x86 code:

x86 代码:

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

回答by Greg Howell

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).

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

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

输出: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

输出:25

回答by Jamin Grey

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

除了前面提到的std::div函数族之外,还有std::remquo函数族,返回rem-ainder 并通过传入的指针获取quo-tient。

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

[编辑:]看起来 std::remquo 毕竟并没有真正返回商

回答by Jon

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 divmethod will calculate both values for you at once.

可能是您提供的三个选项中最好的一个。但是,正如其他答案中所述,该div方法将一次为您计算两个值。

回答by brac37

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.

在 32 位英特尔平台上,您不能在这里使用 64 位整数信任 g++ 4.6.3。a/b 通过调用 divdi3 计算,a%b 通过调用 moddi3 计算。我什至可以想出一个例子,用这些调用计算 a/b 和 ab*(a/b)。所以我使用 c=a/b 和 ab*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).

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

回答by Sinthet

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

您可以使用模数来获得余数。尽管@cnicutar 的回答看起来更清晰/更直接。