Вычисление экспоненты
Вычисляю экспоненту по формуле Тейлора:
long double cust_exp(double x) {
long double rememberX = x;
long double returnValue = 1. + x;
/* for (int k = 2; k <= 150; k++) {
x = x * rememberX;
returnValue = returnValue + x/fact(k);
}*/
returnValue = 1;
for (int i = 150; i > 0; --i) {
returnValue = 1. + x * returnValue / i;
}
return returnValue;
}
long double fact(int k) {
long double n = 1;
long double returnValue = 0;
for (int i = 1; i <= k; i++) {
n = n * i;
}
returnValue = n;
return returnValue;
}
Закоменченное это то же самое через факториал, только из-за факториала дольше. Нужно с точностью до 6ти знаков после запятой по сравнению с оригинальной функцией. Но вот при степенях больше 20 начинаются расхождения уже на 6м знаке. Есть ли какой-то другой способ расчёта, более точный?
Ответы (1 шт):
NB: скорее всего все версии достаточно точны. Проблема в том что double не может представлять большие числа достаточно точно.
Так будет точнее:
double exp_(double x) {
double sum = 1;
double term = 1;
for (int i = 1; i < 150; ++i) {
term *= x / i;
sum += term;
}
return sum;
}
Ещё лучше для больших экспонент использовать формулу ex = (ex/2)2.
Проанализируем ошибку для x = 22.
exp (22) = 3584912846.13159179687500000000 exp_(22) = 3584912846.13159275054931640625 разница = 9.5367431640625 * 10^-7 относительная ошибка: 2.66 * 10^-16
Это очень маленькая ошибка. Например, относительная ошибка между соседними вещественными числами равна 2.22 * 10^-16. То есть, наша функция почти рядом с библиотечной, отличаются только два последних бита мантиссы.