在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)扩展名。
答案 0 :(得分:4)
首先,是的,这种行为与C ++ 11标准一致(尽管不是C ++ 03),在第26.8节第11段中说:
此外,还应有足够的额外过载来确保:
如果对应于double参数的任何参数的类型为long double,则对应于double参数的所有参数都有效地转换为long double。
否则,如果对应于double参数的任何参数具有double类型或整数类型,则对应于double参数的所有参数将被有效地转换为double。
- 醇>
否则,所有与double参数对应的参数都会被有效地转换为float。
(除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} }}