double pow(double, int);
尚未從規範中刪除。它只是被重新編寫。它現在居住在[c.math]/p11。它是如何計算的是一個實現細節。已更改的唯一的C++ 03的簽名是:
float pow(float, int);
這現在返回雙:
double pow(float, int);
而且這變化是爲了與C兼容完成。
澄清:
26.8 [CMATH]/P11表示:
此外,應再 重載足以確保:
如果對應於任何參數雙參數的類型爲long double, 則所有參數對應於 雙參數有效地投擲 長雙。
否則,如果對應於一個雙參數 任何參數的類型爲雙或整數類型, 則對應於 雙參數所有參數都是有效投 翻一番。
否則,對應雙參數所有參數都是 有效地轉換爲浮動。
這一段意味着重載一大堆,包括:
double pow(double, int);
double pow(double, unsigned);
double pow(double, unsigned long long);
等。
這些可能是實際的重載,或者可能使用受限模板實現。我親自實施了這兩種方式,並強烈支持受限制的模板實施。
二更新來解決問題的優化:
實現被允許以優化任何過載。但回想一下,優化應該是只有那。優化的版本應該返回相同的答案。像pow這樣的函數的實現者的經驗是,當你遇到麻煩時,要確保你的實現採用一個整數指數給出與採用浮點指數的實現相同的答案,那麼「優化」通常會比較慢。
作爲示範下面的程序打印出pow(.1, 20)
兩次,使用std ::戰俘,並使用「優化」算法取整指數的優勢第二次一次:
#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
還是以16進制:
0x1.79ca10c92422bp-67
0x1.79ca10c924232p-67
是的,pow的實現者真的擔心低端的所有位。
所以,雖然有自由是爲了將pow(double, int)
轉換爲單獨的算法,但我知道的大多數實現者已經放棄了該策略,可能除了檢查非常小的積分指數。在這種情況下,通過浮點指數實現檢查通常是有利的,以便爲您的優化降壓獲得最大的回報。
C++ 03呢? – 2011-04-11 20:21:54
優化的好機會是用於實現bignum,而不是用於最有可能支持硬件的'double',也可以使用log + mul + exp解決方案。 – 6502 2011-04-11 20:22:29
@ Ben Voigt:C++ 03與此相匹配。 – 2011-04-11 20:24:18