为什么g ++ -O3不会将除法改为乘法?

时间:2017-06-27 03:19:24

标签: c++ g++

我认为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

为什么?

1 个答案:

答案 0 :(得分:1)

编译器通常会尝试遵循IEEE754。在该标准中,确切地定义了除法。这意味着,对于每个a/b,都有一个确切的答案。如果将其修改为a*(1/b),结果可能会略有不同(如果您使用16位有效数字打印双打,可能会看到此效果)

编译器通常可以选择放松它。 GCC有-ffast-math,VC有/ fp:fast。