Ada*_*m S 5 c++ integer-division
你可以这样写:
int i = 3;
int k = 2;
int division = i / k;
int remainder = i % k;
Run Code Online (Sandbox Code Playgroud)
似乎认为这将在低级别上要求ALU执行两个视觉操作:一个返回商,一个返回余数.但是,我相信ALU最有可能在一次操作中计算两者.如果是这种情况,这不是最佳效率.
是否有更有效的方法,而不要求CPU计算两次?换句话说,它可以在C++的单个操作中完成吗?
实际上,您编写的代码不会生成任何除法指令,因为编译器可以在编译时计算出结果.我写了一个小测试程序并设置编译器(VC++ 10SP1)来生成汇编代码清单.
#include <iostream>
using namespace std;
struct result {
long quotient, remainder;
};
result divide(long num, long den) {
result d = { num / den, num % den };
return d;
}
int main() {
result d = divide(3, 2);
d = divide(10, 3);
cout << d.quotient << " : " << d.remainder << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我必须以这种方式编写它,并明确告诉编译器不要内联任何函数.否则编译器会愉快地优化大部分代码.以下是除法函数的结果汇编代码.
; 8 : result divide(long num, long den) {
00000 55 push ebp
00001 8b ec mov ebp, esp
; 9 : result d = { num / den, num % den };
00003 99 cdq
00004 f7 7d 08 idiv DWORD PTR _den$[ebp]
; 10 : return d;
; 11 : }
00007 5d pop ebp
00008 c3 ret 0
Run Code Online (Sandbox Code Playgroud)
它足够聪明,可以生成单个IDIV指令并使用它生成的商和余数.现代C和C++编译器在这种优化方面已经非常擅长.除非您遇到性能问题并且已经分析了代码以确定瓶颈在哪里,否则不要试图再次猜测编译器.
当然:
int i = 3;
int k = 2;
int division = i / k;
int remainder = i - division * k;
Run Code Online (Sandbox Code Playgroud)
另外,如果你真的想这样做,那么看看div,我怀疑它更快,就像我上面的解决方案一样.
ISO C99具有以下ldiv功能:
#include <stdlib.h> ldiv_t ldiv(long numer, long denom); The ldiv() function computes the value numer/denom (numerator/denominator). It returns the quotient and remainder in a structure named ldiv_t that contains two long members named quot and rem.
无论是在FPU级别还是单一操作我都说不出来.