Предисловие
Навязчивая идея посчитать синус угла, используя простые мат. операции появилась еще давно, и я, тихим вечером копаясь в Desmos'е, обнаружил сходство графика обычной функции-треугольника, возведенной в некоторую степень, с полу периодом синуса, тогда-то ко мне и пришло просветление!
Начало
Для начала была создана та самая функция с периодом в, которая должна в дальнейшем станет нашей синусоидой:
Результат деления с остатком имеет диапозон , что не соответствует диапазону значений синуса , так что делим результат на , что дает нам необходимый диапазон , который в дальнейшем позволит нам получить необходимую форму графика.
После приведения диапазона к необходимому виду - превращаем функцию к необходимой форме треугольника. Для этого необходимо вычесть из нее единицу и взять модуль от получившегося числа.
Сходство
На выше приведенном изображении можно увидеть 2 графика:
Зеленый - синус
Красный - наша функция ( функция инвертирована ), возведенная в степень 1.7, подобранную методом тыка.
После сопоставления графиков отлично видно их сходство. Из-за сходства сложно разглядеть график синуса, так сильно они сходятся с подобранной степенью.
Знак периода
Нашей функции не хватает знака периода. его очень просто получить, используя то же самое деление с остатком:
Ее период не совпадает с необходимым, так что инвертируем ее:
И получим ее знак, используя функцию калькулятора:
Получаем следующий график:
Теперь умножим нашу функцию-"недосинус" на функцию знака:
Получаем следующий график:
Уже очень похоже, но не то. Нужно избавиться от магической константы 1.7.
Магическая константа
Особо заморачиваться на станем. Просто выдернем необходимый кусок функции и найдем необходимую степень через логарифм:
Таким образом считаем значение магической константы. Дадим имя константе, например .
Таким образом наша функция стала выглядеть следующим образом:
И отличие от графика "калькуляторного" синуса стало совсем незаметно на графике.
Погрешность
Данная формула имеет незначительную погрешность относительно "калькуляторной". Стоит ее посчитать.
Для подсчета возьмем угол 45 градусов, поскольку именно при таком значении наблюдается наибольшая погрешность.
Для измерения погрешности просто посчитаем расстояние от точек на окружностях, нарисованный с помощью "калькуляторного" синуса и нашей формулы.
Получаем следующее значение:
Погрешность крайне мала, потому, считаю, ей можно пренебречь.
Заключение
Создание данной функции не было подкреплено каким-либо поводом. Она была создана исключительно в целях саморазвития и утешения внутренней навязчивой идеи.
Благодарю за прочтение статьи. *занавес*
Комментарии (25)
mobi
03.08.2022 13:21+7В точке pi/4 значения будут совпадать в точности, поэтому возьмите лучше pi/8. А еще лучше постройте и приведите в статье график ошибки от аргумента.
UrsusPuh
03.08.2022 13:45+2А у меня есть арктангес через аппроксимацию полиномом второй степени. Аппроксимируется собсно четверть окружности, потом всё сводится к ней. Надо было для обработки сквт. Собсно по четвертям окружности:
t = arctan(sin/cos)
t = PI/2-arctan(cos/sin)
t = PI/2+arctan(-cos/sin)
t = PI-arctan(sin/-cos)
t = -PI+arctan(-sin/-cos)
t = -PI/2-arctan(-cos/-sin)
t = -PI/2+arctan(cos/-sin)
t = -arctan(-sin/cos)
ф-я аппроксимации: y= -0.0915 x^2 + 0.3434x - 0.0015
если x < 0.1 то y = x;
Работает быстро, считать можно даже без плавающей точки.sepetov
03.08.2022 13:52+17Просто оставлю это здесь. Вдруг кто не знает.
Приближённая формула для вычисления десятичного логарифма числа X без калькулятора и даже без особых умственных усилий:
Целая часть - количество цифр в числе X минус один.
Дробная часть - первая цифра числа X плюс два.
Уточняющее исключение: дробная часть равна первой цифре исходного числа, если она единица или девятка
Примеры:
lg(456) = 2,6
lg(4567) = 3,6
lg(1234) = 3,1
lg(12345) = 4,1
Rsa97
03.08.2022 15:59+3Стоит учесть, что это правило для целых чисел. Для дробных необходимо ещё одно правило
lg(x / 10n) = lg(x) − n
lg(0.456) = lg(456 / 1000) = lg(456) − 3 = −0.4
RumataEstora
04.08.2022 08:03Правила 2 и 3 сомнительны
lg(19) = 1.3
lg(42) = 1.6
lg(45) = 1.7
sepetov
04.08.2022 13:12В первом примере, конечно, есть погрешность в десятых долях ответа. Считая "на глаз" lg(19) якобы должен быть равен 1.1, хотя 1.28 - точнее. Ну, куда деваться? Для кустарных прикидок сойдёт.
Во втором таких расхождений нет. Для lg(42): количество цифр - 2, значит целая часть ответа (2-1)=1. Дробная часть ответа равна 6, так как первая цифра в числе 42 - это цифра 4, а правило предлагает его увеличить на 2.
В третьем примере ответ около 1.65, так что с точностью до десятых результат хороший :-) Жить можно :-)
Rsa97
03.08.2022 14:34+24sin(x°) = 4x(180 − x)/(40500 − x(180 − x)), x ∈ [0, 180°]
Бхаскар I, 629 г. н.э.
fk0
03.08.2022 20:18+2Все калькуляторы считают синусы кордиком (CORDIC). Для чего нужны лишь сдвиги, сложения и простейшие битовые операции. Приведённые же выше способы совсем не тривиальны, так как требуют операций умножения, деления и сложения над числами с плавающей точкой (или большими целочисленными).
Конечно, если есть FPU то разложение в ряд Тейлора -- быстрей. Но на условном 8-битном контроллере быстрей CORDIC.
akhkmed
04.08.2022 00:19Кстати да. CORDIC использовался и в 8087, и в целочисленных системах: например в этой старой статье есть реализация для 16-разрядных типов данных, хотя она может быть адаптирована для любой точности. Он действительно использует только сложение, вычитание и сдвиги и является быстро и гарантированно сходящимся. Возведение в нецелую степень выглядит не такой простой математикой.
maisvendoo
04.08.2022 02:33Теперь поместите вашу существенно нелинейную (с разрывами второго рода) функцию в правую часть дифуры, и наслаждайтесь, пытаясь интегрировать это численно
Refridgerator
04.08.2022 06:22+2По сути, вы пытаетесь аппроксимировать функцию
cos(x·pi/2)
функцией1-xk
на интервале[0,1]
. Проблема в том, что в вычислительном плане в этом нет никакого смысла — вычисление возведения в дробную степень делается через логарифм и экспоненту, а они (особенно логарифм) намного более трудозатратны по сравнению с вычислением непосредственно синуса.
Refridgerator
04.08.2022 06:41+3Навязчивая идея посчитать синус угла, используя простые мат. операции
Держите вариант с тремя знаками после запятой в диапазоне [-pi/2,pi/2]:auddu_k
04.08.2022 09:58+1Так в статье интересен не сам результат, а способ вывода и способ как до этого вывода дошли :-)
Как вот вы получили такой удивительно простой результат?
Refridgerator
04.08.2022 10:21+21. Выбрал для аппроксимации функцию
(a·x+b·x3)/(1+c·x2)
;
2. Составил систему из двух уравнений, определяющих значение (1) функции и производной (0) приx=pi/2
;
3. решение дало значения коэффициентовa
иb
выраженных черезc
;
4. коэффициентc
подобрал экспериментально по графику, визуально минимизируя максимальное отклонение и аппроксимировал его рациональным числом;
5. подставил все значения в исходную функцию и упростил.
Всё это конечно не вручную, а в Mathematica.
Refridgerator
04.08.2022 11:12+3Если вас привлекает простота, то лучше так:
И точнее получается, 4 знака после запятой.
Sergey_zx
04.08.2022 13:23+1Кому по душе арбуз, а кому свиной хрящик.
Хочется точно, следуем учению брата Тейлора. Хочется быстро, делаем таблично.
Keeper13
Даст ли это какой-то выигрыш в скорости вычисления по сравнению с рядом Тейлора, например?
Refridgerator
Нет.