C++获得整数除法和余数的最佳方法
我只是想知道,如果我想将 a 除以 b,并且对结果 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);
神奇的功能可以
同时提供这两种功能?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
在 x86 上,余数是除法本身的副产品,因此任何合格的编译器都应该能够使用它(而不是再次执行
div
)。这可能也在其他架构上完成。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.std::div
返回一个包含结果和余数的结构。std::div
returns a structure with both result and remainder.至少在 x86 上,g++ 4.6.1 仅使用 IDIVL 并从该单个指令中获取两者。
C++ 代码:
x86 代码:
On x86 at least, g++ 4.6.1 just uses IDIVL and gets both from that single instruction.
C++ code:
x86 code:
测试div()和组合除法的示例代码模组。我用 gcc -O3 编译了这些,我必须添加对 doNothing 的调用以阻止编译器优化所有内容(对于除法 + mod 解决方案,输出将为 0)。
对此持保留态度:
输出:150
输出:25
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:
Outputs: 150
Outputs: 25
除了前面提到的std::div 函数系列,还有 std::remquo 系列函数,返回 rem-ainder 并通过传入的指针获取 quo-tient 。
[编辑:] 看起来 std::remquo 在之后并没有真正返回商全部。
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.
在其他条件相同的情况下,最好的解决方案是明确表达您的意图。所以:
可能是您提出的三个选项中最好的一个。然而,正如其他答案中所述,
div
方法将立即为您计算这两个值。All else being equal, the best solution is one that clearly expresses your intent. So:
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.您不能信任 g++ 4.6.3 在 32 位 intel 平台上使用 64 位整数。 a/b 通过调用 divdi3 计算,a%b 通过调用 moddi3 计算。我什至可以想出一个使用这些调用来计算 a/b 和 ab*(a/b) 的示例。所以我使用 c=a/b 和 ab*c。
div 方法调用计算 div 结构的函数,但在硬件支持整型(即 64 位 intel/amd 平台上的 64 位整数)的平台上,函数调用似乎效率低下。
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).
许多答案建议使用以下代码:
但是,值得记住的是,除法与乘法不同,加法的执行时间要长得多(据我所知,与一个时钟周期相比,要执行数十倍的时钟周期)。而且,如果您需要重复计算 mod 和 div,那么值得将两次除法替换为一次除法、一次乘法和一次加法,如下所示:
Many answers suggest using the following code:
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:
您可以使用模数来获得余数。虽然@cnicutar 的答案看起来更干净/更直接。
You can use a modulus to get the remainder. Though @cnicutar's answer seems cleaner/more direct.