指數近似代碼基於裁縫系列https://en.wikipedia.org/wiki/Taylor_series圍繞零可以很好地用於輸入,但移動在兩個方向上更遠時是完全無用的。下面是我的小測試代碼的輸出,相比的std :: EXP結果,並在邊境的錯誤是巨大的內-12至12的範圍和打印錯誤計算輸入EXP。對於-12輸入例如誤差約爲高達148255571469%:指數近似不是小的或大的輸入良好
in = -12 error = 148255571469.28%
in = -11.00 error = 18328703925.31%
in = -10.00 error = 2037562880.10%
in = -9.00 error = 199120705.27%
in = -8.00 error = 16588916.06%
in = -7.00 error = 01128519.76%
in = -6.00 error = 00058853.00%
in = -5.00 error = 00002133.29%
in = -4.00 error = 00000045.61%
in = -3.00 error = 00000000.42%
in = -2.00 error = 00000000.00%
in = -1.00 error = 00000000.00%
in = 0.00 error = 00000000.00%
in = 1.00 error = 00000000.00%
in = 2.00 error = 00000000.00%
in = 3.00 error = 00000000.00%
in = 4.00 error = 00000000.03%
in = 5.00 error = 00000000.20%
in = 6.00 error = 00000000.88%
in = 7.00 error = 00000002.70%
in = 8.00 error = 00000006.38%
in = 9.00 error = 00000012.42%
in = 10.00 error = 00000020.84%
in = 11.00 error = 00000031.13%
in = 12.00 error = 00000042.40%
我需要一個誤差近似小於跨越儘可能大的範圍內1%的誤差。任何想法如何實現這一目標?
我的小測試,代碼如下:
#include <cmath>
#include <iostream>
#include <iomanip>
double my_exp(double x) //based on https://en.wikipedia.org/wiki/Exponential_function
{
double res = 1. + x, t = x;
unsigned long factorial = 1;
for (unsigned char i = 2; i <= 12; ++i)
{
t *= x, factorial *= i;
res += t/factorial;
}
return res;
}
int main(int argc, char* argv[])
{
for (double in = -12; in <= 12; in += 1.)
{
auto error = std::abs(my_exp(in) - std::exp(in));
auto percent = error * 100./std::exp(in);
std::cout << "in = " << in << " error = "
<< std::fixed << std::setw(11) << std::setprecision(2)
<< std::setfill('0') << percent << "%" << std::endl;
}
return 0;
}
從看似類似的問題的解決方案從「大約E 1 X」 Approximate e^x不解決這個問題:基於雷米茲和帕德逼近
- 解決方案只有有限的範圍內提供準確度(https://stackoverflow.com/a/6985347/5750612)
- E 1 X = 2×/ LN(2)歸結POW的toapproximation和我無法找到精確的一個
- 裁縫系列不爲小和大的投入工作
- expf_fast溶液產生更均勻的誤差在所有範圍內,但它仍然是過大(〜在範圍的端部20%)
的可能的複製[大致E 1 X](https://stackoverflow.com/questions/6984440/approximate-ex) – jodag