double pow(double, int);
尚未从规范中删除。它只是被改写了。它现在位于 [c.math]/p11 中。如何计算是一个实现细节。唯一改变的 C++03 签名是:
float pow(float, int);
现在返回双倍:
double pow(float, int);
And this为了 C 兼容性而进行了更改。
澄清:
26.8 [cmath] / p11 说:
此外,还应有额外的
过载足以确保:
如果任何对应于 double 形参的实参的类型为 long double,
那么所有参数对应于
双参数被有效地转换
至长双倍。
否则,如果任何参数对应于双参数
具有 double 类型或整数类型,
那么所有参数对应于
双参数被有效地转换
加倍。
否则,与双参数对应的所有参数都是
有效地投射到漂浮状态。
本段暗示了一大堆重载,包括:
double pow(double, int);
double pow(double, unsigned);
double pow(double, unsigned long long);
etc.
这些可能是实际的重载,或者可以使用受限模板来实现。我个人已经用这两种方式实现了它,并且强烈支持受限模板实现。
解决优化问题的第二次更新:
允许实现优化任何过载。但请记住,优化应该是only那。优化版本应该返回相同的答案。像 pow 这样的函数的实现者的经验是,当您费尽心思确保采用积分指数的实现与采用浮点指数的实现给出相同的答案时,“优化”通常会更慢。
作为演示,以下程序打印出pow(.1, 20)
两次,一次使用 std::pow,第二次使用利用积分指数的“优化”算法:
#include <cmath>
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setprecision(17) << std::pow(.1, 20) << '\n';
double x = .1;
double x2 = x * x;
double x4 = x2 * x2;
double x8 = x4 * x4;
double x16 = x8 * x8;
double x20 = x16 * x4;
std::cout << x20 << '\n';
}
在我的系统上打印出:
1.0000000000000011e-20
1.0000000000000022e-20
或者用十六进制表示法:
0x1.79ca10c92422bp-67
0x1.79ca10c924232p-67
是的,pow 的实现者确实担心所有这些低端的位。
所以虽然有洗牌的自由pow(double, int)
转向单独的算法,我知道的大多数实现者都放弃了该策略,除了检查非常小的积分指数之外。在这种情况下,将检查放入带有浮点指数的实现中通常是有利的,以便为您的优化带来最大的收益。