C ++ 11是否强制执行pow(double,int)以使用较慢的pow(double,double)?

时间:2013-09-18 13:07:42

标签: c++ gcc c++11 c++-standard-library

在C ++ 03中,使用例如std::pow(double_val, 6)比使用std::pow(double_val, 6.0)要快得多。

使用C ++ 11进行编译时不再是这种情况。从gcc的libstdc ++ - 4.8中查看cmath头文件,可以看到显式的pow(double,int)不再存在,这种情况由以下模板处理,该模板将int提升为double:

template<typename _Tp, typename _Up>
inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
pow(_Tp __x, _Up __y) {
  typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
  return std::pow(__type(__x), __type(__y));
}

这种行为是在C ++ 11标准中还是未来的libstdc ++实现会返回到更快的方法?

其次,如果出于标准或实施原因,更快的行为不再可能,再次实现它的最便携方式是什么?我在&#34; ext / numeric&#34;下的gcc stdlibc ++中看到power(...)函数,但这被标记为非标准 SGI(rip)扩展名。

2 个答案:

答案 0 :(得分:4)

首先,是的,这种行为与C ++ 11标准一致(尽管不是C ++ 03),在第26.8节第11段中说:

  

此外,还应有足够的额外过载来确保:

     
      
  1. 如果对应于double参数的任何参数的类型为long double,则对应于double参数的所有参数都有效地转换为long double。

  2.   
  3. 否则,如果对应于double参数的任何参数具有double类型或整数类型,则对应于double参数的所有参数将被有效地转换为double。

  4.   
  5. 否则,所有与double参数对应的参数都会被有效地转换为float。

  6.   

(除float的重载外 - 仅限double - 仅限long double - 仅限。{/ p>

所以实现的实现已经将整数参数强制转换为double而我认为合规库不可能提供更快的std::pow对于整数幂,除了可能检查double参数的完整性(是一个单词吗?)并在这种情况下使用特殊路径。

为了提供一种独立于平台的更快方式,我唯一想到的就是编写一个自定义包装器,如果它存在,则委托给这个非标准power。除此之外,我不知道如何在不编写自己的实现的情况下再次将该行为注入std::pow

编辑:然而,在查看this answer时,只要行为与std::pow(double(x), double(y))完全相同,实体仍然可以为整数幂提供优化的重载。因此,实现提供更快的版本是可能的,但我不会像在C ++ 03中那样对此进行如此大的评价(其中恕我直言,即使是标准的一部分,但我可能错了)

答案 1 :(得分:2)

C只提供double pow(double, double)重载(回想一下C不允许函数重载)。 C ++ 11标准(26.8 / 9)表示在命名空间std中添加了以下重载(除了C之外):

float pow(float, float);
long double pow(long double, long double);

因此,double pow(double, int)是一个扩展而不是标准函数。因此,实现可能会提供或不提供。

编辑在Christian Rau评论和回答之后。

现在我相信过载一定存在。因此,应该有double pow(double, int)超载。但是,这个重载必须(正如他在回答中所说)将int投射到double并致电double pow(double, double)

实际上有很多重载。提供它们的最简单方法不是正常的函数,而是作为模板函数,与OP中显示的libstdc ++实现完全一样。

另请参阅{Houtant详细解释详情的this公开问题。

最后,Hulk提供的link非常相关,Howard Hinnant(再次)解释说几乎没有理由提供一个优化的重载,它可以将int转换为{{1} }}