Задача 1
Условия задачи
Сначала базовый ввод вывод:
int main() {
int N;
double x; // используем double тк по условию понадобится точность 10^-15
scanf("%d", &N);
for (int i = 0; i < N; ++i){
scanf("%lf", &x); // считваем в буфер число
printf("%.15g\n", exp(x)); // вызываем функцию экспоненты и сразу выводим ответ
// ^^^^^ выводим как нас попросили по условию для точности, а именно:
// .15 значит до 15 знаков после запятой и g - выводит число как обычный %f если помещается,
// а если нет, то в экспоненциальном виде %e (1.3456e+56)
}
return 0;
}
Осталось по мелочи реализовать exp(x)
:
double exp(double x) {
if (x < 0) return 1.0 / exp(-x);
...
}
Во первых, помним что , так что как только видим отрицательное число просто делим 1
на эту же функцию, но уже с положительным x
(минус на минус = плюс) и не паримся с отрицательным иксом.
Итак... Что за ряды Тейлора и как нам при помощи этого считать экспоненту. По википедии, это разложение функции в бесконечную сумму степенных функций, про это всё вам расскажут/уже рассказали на мат анализе. Но суть в том что для решения задачи нам нужно релизовать подсчёт экспоненты через этот ряд Маклорена:
Считать до бесконечности мы пока не будем: по условию у нас дана точность , следовательно считать будем то тех пор пока элемент последовательности больше (ведь элементы меньше не будут вносить эффект для желаемой точности)
Интуитивно, мы просто в цикле мы будем вычислять элементы последовательности и суммировать их, для вычисления нам надо посчитать степень x
и факториал, но такой подход является не очень эффективным.
Заметим, что нам необязательно снуля считать весь элемент, а достаточно предыдущий домжнодить на x
и разделить на n
. К примеру: x=5
,n=3
, . Мы хотим посчитать следующий элемент с n=4
, и вместо того чтобы считать всё заного мы домнажаем . Теперь нам нужно просто реализовать это в коде, причём весьма просто
double exp(double x) {
if (x < 0) return 1 / exp(-x);
int n = 1; // номер текущего элемента
double sum=1, term=1; // сумма элементов, последний элемент последовательности
// мы сразу добавляем первый элемент 1 (см формулу), поэтому сумма 1 и последний элемент 1
while (term > 1e-15) { // пока (последний элемент влияет на точность)
term = term * x / n++; // чтобы считать следующий элемент домнажаем текущий на x и делим на n
// ^^^ в той же строке увеличиваем n (постфиксно, сначение используется старое)
sum += term; // добавляем элемент к общей сумме
}
return sum; // возвращаем сумму
}
И плов готов!
Полный код:
#include <stdio.h>
double exp(double x) {
if (x < 0) return 1 / exp(-x);
double sum = 1,term = 1;
int n = 1;
while (term > 1e-15) {
term = term * x / n++;
sum += term;
}
return sum;
}
int main(void){
int N;
double x;
scanf("%d", &N);
for (int i = 0; i < N; ++i){
scanf("%lf", &x);
printf("%.15g\n", exp(x));
}
return 0;
}