VC2005EEの/O2で。
pow
powはべき乗で、pow(a, b)でabを計算する。
おそらく、bがdoubleの場合は、
ab = exp(b * log(a))
としている。
bがintの場合は、例えば8乗なら、
b *= b; b *= b; b *= b;
で3回の積で求まる、
といったアルゴリズムを使う。
bを振ると、
2.7 10.855s
4 0.889s
16 1.648s
64 2.266s
256 3.196s
1024 5.469s
4096 6.258s
16384 7.103s
65536 8.184s
262144 18.534s
よほどbが大きくならない限りintを使ったほうがいい。
bがdoubleのときはかかる時間に大きさによらないと思えるが、
intの場合はlog(b)にほぼ線形である。
しかし、10万あたりから急に時間がかかるようになる。
#include
#include
#include#pragma comment (lib, "winmm.lib")
using namespace std;
const int N = (int)1e8;
const double dx = 0.1 / N;void bench_pow_double(double k) {
int t = timeGetTime();
double sum = 0;
double x = 0.95;
for(int i = 0; i < N; i++) {
sum += pow(x, k);
x += dx;
}
fprintf(stdout, "%.3fs\n", (timeGetTime() - t) * 1e-3);
fprintf(stdout, "%e\n", sum);
}void bench_pow_int(int k) {
int t = timeGetTime();
double sum = 0;
double x = 0.95;
for(int i = 0; i < N; i++) {
sum += pow(x, k);
x += dx;
}
fprintf(stdout, "%.3fs\n", (timeGetTime() - t) * 1e-3);
fprintf(stdout, "%e\n", sum);
}void main() {
bench_pow_double(2.7);
for(int i = 1; i < 10; i++) {
int k = 1 << (2 * i);
bench_pow_int(k);
}
}