Найти тему
Я, Golang-инженер

#20. Ряд Тейлора в Golang для числа Эйлера e^x

Это статья об основах программирования. На канале я рассказываю об опыте перехода в IT с нуля, структурирую информацию и делюсь мнением.

Хой, джедаи и амазонки!

Мы привыкли легко решать простые задачи, например 5х5 или возвести 5 в куб. А как насчёт пяти в степени 1/2? Или синус 22,5 градусов? Или e в степени 14?

Определение e из wiki:

Число e, также известное как число Эйлера, является математической константой, приблизительно равной 2,71828, и может быть охарактеризовано многими способами. Это основа натурального логарифма. Это предел (1 + 1/n)n по мере приближения n к бесконечности, выражение, возникающее при изучении сложных процентов.

Да, вы можете возразить - мол, это всё делает excel или даже калькулятор. И будете правы:

Калькулятор - возведение в произвольную степень
Калькулятор - возведение в произвольную степень

Вопрос в том, как это делает калькулятор?

Ответ: многие функции можем разложить в ряд Тейлора. Об этом можно изучить много теории, там есть сложности. Например, проблема в том, что этот ряд не всегда сходится. А если сходится, то не всегда к той функции, из которой получен.

Для обучения программированию этих сложностей пока не нужно. Ну, если очень хочется, можно посмотреть это толковое видео. А для программирования, прежде чем перейти к построению рядов Тейлора, следует сказать о типе данных с плавающей запятой (с плавающей точкой).

Когда мы используем переменную с плавающей точкой, речь идёт о "приблизительных значениях", посмотрите сами:

Пример сложения числа с плавающей точкой
Пример сложения числа с плавающей точкой

Переходим к числу Эйлера. Формулу ряда Тейлора для числа Эйлера:

Формула ряда Тейлора для числа Эйлера
Формула ряда Тейлора для числа Эйлера

Как описать эту формулу в Golang?

Первое - нужно разобраться с факториалом: n!

Помните, как школы программирования, завлекая на свои курсы, говорят, что математику знать особенно не нужно. Может и не нужно при поступлении, но математику вы изучите во время обучения программированию. Или вряд ли вы станете программистом.

Итак, факториал - уж не помню, в институте с ним познакомился, или ещё в школе. Не суть. Факториал числа - произведение всех натуральных чисел до этого числа включительно. Обозначается n!, например 5! или 79!

Значения факториалов растёт очень быстро, я бы сказал, в геометрической прогрессии:

0! = 1
1! = 1
2! = 1 х 2 = 2
3! = 1 х 2 х 3 = 6
4! = 1 х 2 х 3 х 4 = 24
5! = 1 х 2 х 3 х 4 х 5 = 120

Второе - наша задача не суммировать ряд до бесконечности в Golang, а остановиться на приемлемом нам значении. Как мы определяем приемлемое для нас значение?

Очевидно, что чем больше значений в ряде будет просуммировано, тем точнее будет полученное число. Помните, как в романе Яна Мартела и одноимённой экранизации фильма "Жизнь Пи", Писин Патель писал на доске сотни цифр после запятой числа Пи? Сколько там? 3,14 - а дальше? Ну, в лучшем случае мы помним, что Пи равно 3,1415. Если вы помните больше - у вас +100 к memory.

Кадр из фильма "Жизнь Пи"
Кадр из фильма "Жизнь Пи"

Проще всего в точности суммирования выбрать количество знаков после запятой, до которой нам нужно знать значение. И мы будем сравнивать в Go результат каждого нового суммирования с предыдущим суммированием. И когда разница между ними достигнет заданной погрешности, мы останавливаем суммирование и выдаём результат.

Как описать точность в Go? Например, пользователю предлагается ввести число, которое показывает, сколько знаков после запятой должно быть в искомом числе без изменения, в случае увеличения точности. Например, для 3,14 точность будет равно 2 (два знака после запятой). А для 3,1415 - точность будет равна 4.

Так выглядит готовый код:

package main

import (
"fmt"
"math"
)

func main() {
fmt.Println("***Ряд Тейлора для e^x***")
fmt.Println("--------------------")
fmt.Println("Введите значение x:")
var x float64
fmt.Scan(&x)
fmt.Println("Введите количество знаков после запятой - точность вычисления:")
var n float64
fmt.Scan(&n)
epsilon := 1 / math.Pow(10, n)//перевод в "понятную" программе точность
fmt.Printf("Точность вычисления до разницы в: %v \n", epsilon)
fmt.Println("--------------------")
result := 0.0
prevResult := 0.0
fact := 1//начальное значение факториала
k := 0

for {//цикл бесконечный до выполнения проверки точности
if k > 0 {
fact *= k
}
result += math.Pow(x, float64(k)) / float64(fact)
fmt.Println(result)

if math.Abs(result-prevResult) < epsilon {//проверка точности - в принципе, условие с определёнными манипуляциями, можно поставить после for, чтобы было на виду
break
}
prevResult = result
k++
}
fmt.Printf("Значение e равно %v с точностью %v", result, epsilon)
}

Результат кода:

Результат выполнения кода
Результат выполнения кода

В этом коде отображаются итерации сложения числа Эйлера в ряде Тейлора. Код выполнялся, пока для двух значений 2.71827876984127 и 2.7182815255731922 пятый знак после запятой не стал в допуске, задаваемым пользователем, т.е. числа стали равны +/-0.00001.

Бро, ты уже здесь? 👉 Подпишись на канал «Я, Golang-инженер», будем изучать IT вместе 👨‍💻👩‍💻👨‍💻

Наука
7 млн интересуются