我认为g ++ -O3会自动将除法改为乘法。但是根据这段代码:
#include <iostream>
#include <sys/time.h>
double compute0(int i) {
double d_2 = i * i;
double ret = 0;
for (int j = 0; j < 1000000; j++) {
ret += j;
}
return ret;
}
double compute1(int i) {
double d_2 = i * i;
double ret = 0;
for (int j = 0; j < 1000000; j++) {
ret += j / d_2;
}
return ret;
}
double compute2(int i) {
double d_2 = i * i;
double d_2_inv = 1.0 / d_2;
double ret = 0;
for (int j = 0; j < 1000000; j++) {
ret += j * d_2_inv;
}
return ret;
}
double tik() {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec * 1e-6;
}
int main() {
{
double begin = tik();
double ret = 0;
for(int i = 1; i < 100; i++)
ret += compute0(i);
double end = tik();
std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl;
}
{
double begin = tik();
double ret = 0;
for(int i = 1; i < 100; i++)
ret += compute1(i);
double end = tik();
std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl;
}
{
double begin = tik();
double ret = 0;
for(int i = 1; i < 100; i++)
ret += compute2(i);
double end = tik();
std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl;
}
return 0;
}
输出是:
费用时间:0.105436 ret:4.95e + 13
费用时间:0.453676 ret:8.17441e + 11
费用时间:0.203873 ret:8.17441e + 11
为什么?
答案 0 :(得分:1)
编译器通常会尝试遵循IEEE754。在该标准中,确切地定义了除法。这意味着,对于每个a/b
,都有一个确切的答案。如果将其修改为a*(1/b)
,结果可能会略有不同(如果您使用16位有效数字打印双打,可能会看到此效果)
编译器通常可以选择放松它。 GCC有-ffast-math,VC有/ fp:fast。