
Сообщение от
Рогов Алексей
Добрый день!
Алиса и с синусом готова помочь:
если просто написать дай функцию без анализа что она пишет то наверное будут претензии вот прокрученная второй раз с уточнением что она эксперт в промышленной атоматизации
Оптимизированный вариант (рекуррентная формула)
Код:
FUNCTION SinTaylorOptimized : REAL
VAR_INPUT
x : REAL; // Угол в радианах
tolerance : REAL := 1E-6; // Точность (по умолчанию)
END_VAR
VAR
pi : REAL := 3.1415927; // Достаточно для 32-битного REAL
two_pi : REAL := 2.0 * pi;
term : REAL; // Текущий член ряда
x_sq : REAL; // x² (вычисляется один раз)
n : UDINT := 1; // Счётчик итераций (начинаем с 1 для второго члена)
END_VAR
// === ШАГ 1: Нормализация к [-π, π] за О(1) ===
x := x - two_pi * TRUNC(x / two_pi); // Быстрое приведение через целую часть
IF x > pi THEN
x := x - two_pi;
ELSIF x < -pi THEN
x := x + two_pi;
END_IF;
// === ШАГ 2: Рекуррентное вычисление ряда ===
SinTaylorOptimized := x; // Первый член: x
term := x;
x_sq := x * x; // x² вычисляем один раз
// Итерации: term_{k} = -term_{k-1} * x² / ((2k)*(2k+1))
WHILE ABS(term) >= tolerance DO
term := -term * x_sq / REAL(2 * n) / REAL(2 * n + 1);
SinTaylorOptimized := SinTaylorOptimized + term;
n := n + 1;
END_WHILE;
END_FUNCTION
Ключевые улучшения:
Рекуррентная формула
termₙ = -termₙ₋₁ · x² / ((2n)·(2n+1)) — исключает степень и факториал.
Нормализация за константное время
Через TRUNC(x / 2π) вместо цикла.
Минимизация операций
3 арифметические операции на итерацию против 2n в исходном коде.
Безопасность для ПЛК
Нет риска переполнения, стабильная работа с 32-битным
Важно для промышленного применения: Для критичных к скорости задач (цикл ПЛК < 10 мс) рекомендуется использовать аппаратную функцию SIN() из библиотеки ПЛК — она реализована через таблицы и полиномы Чебышёва и работает в 10–100 раз быстрее. Ряд Тейлора оправдан только при отсутствии встроенной функции или для учебных целей.