-
Здравствуйте!
Может у кого-то завалялась готовая функция/либа для быстрого приблизительного расчёта синуса? Типа по приближённым формулам или из таблицы?
Стандартный дюже долго думает, а мне и не надо большой точности.
Надо кое-то быстро протестить, а делать свой велосипед с нуля долго и не факт что сделаю достаточно оптимально, а гугл что-то шлёт не в тему.
Спасибо!
-
синус приблизительно равен косинусу. погрешность меньше единицы
-
что мешает заполнить таблицу и брать значения из нее?
-
Жуткая спешка и врождённая непереносимость тригонометрии. :3
Пока так набросал, но что-то нифига не улучшилось:
Unit FastSinCos;
Interface
Function FastSinTable(Const X: Real): Real;
Implementation
Var SinTable: Array [-3000 .. 3000] Of Real;
Procedure InitSinTable();
Var X: Integer;
Begin
For X:=Low(SinTable) To High(SinTable) Do
SinTable[X]:=Sin(X/10);
End;
Function FastSinTable(Const X: Real): Real;
Begin
Result:=SinTable[Trunc(X*10)];
End;
Initialization
InitSinTable();
Finalization
End.
Или я совсем криволапый, или тормозит не там где ожидалось... гм...
-
это типа синусы для градусов цельсия?
круто
-
Если я еще не совсем забыл Delphi, то нужно просто заменить Real на Extended и использовать стандартную Sin. То есть, заставить работать сопроцессор, а быстрее него вряд ли что придумаешь.
-
просто интересно, зачем таблица синусов длиной в 600 радиан.
-
просто интересно, зачем таблица синусов длиной в 600 радиан.
-
> rrrrr © (28.03.17 20:33) [7]
слишком короткая?
-
в военное время на сотом обороте говорят значения синуса начинают плавать
-
Смысла в таблице нет. Процессоры Pentium II-III и выше считают синус быстрее чем чтение из таблицы (памяти). Так что если что-то вращать надо то вот:
type
PFloatPoint = ^TFloatPoint;
TFloatPoint = record
fX, fY: double;
end;
const
PIdiv180: float = (PI / 180);
function RotatePoint(Angle: Float; cP, dP: TFloatPoint): TFloatPoint;
var
lpSin, lpCos: Float;
P: TFloatPoint;
lpRad: Float;
begin
lpRad := Angle * PIdiv180;
lpSin := Sin(lpRad);
lpCos := Cos(lpRad);
//Смещение к центру вращения
P.fX := dP.fX - cP.fX;
P.fY := dP.fY - cP.fY;
//Вращение точки и возврат на место
Result.fX := (P.fX * lpCos - P.fY * lpSin) + cP.fX;
Result.fY := (P.fX * lpSin + P.fY * lpCos) + cP.fY;
end;
-
CP - центр вращения
DP - удаленная точка
-
> просто заменить Real на Extended
Ничего не изменилось.
> просто интересно, зачем таблица синусов длиной в 600 радиан.
Просто рантайм замерял минимальную и максимальную значению того что в моём конкретном случае может передаваться в SinEx(): [ -217,21 .. 247,96 ] - и эдак округлил в большую сторону. %) Для наколенного теста сойдёт)
> заставить работать сопроцессор, а быстрее него вряд ли что придумаешь.
Вроде ж как как минимум приближённый на процессоре быстрее чем тот что на сопроцессоре (который делает с этакой хорошей точностью), не?
> считают синус быстрее чем чтение из таблицы
Почему вдруг?
Короче придётся выкидывать выходной и мерять скорость выполнения и точность разных вариантов по старинке...
-
о я понял всю гениальность замысла
чувак одной таблицей убивает двух зайцев.
1. подменяет медленный sin
2. длинной таблицы подменяет медленный x mod 2pi
-
осталось заменить четыре арифметических на таблицы брадиса и логлинейку
вообще летать будет
-
>Почему вдруг?
SSE - 1 такт
-
Я же написал - у меня непереносимость тригонометрии. Не понимаю я эти радианы, чтоб их. Помню тока что 2pi это окружность или её половина.
гм... mod 2pi, спасибо, звучит логично, ток а ничё что "x" и "2pi" в плавающие?)
> SSE - 1 такт
И давно ли Делфи7 выполняет Sin() при помощи SSE?)))
А текущие версии серьёзно на нём чтоле? о___О
-
плавающие и чо.
плавающий остаток от деления на круг никуда не делся
-
Нельзя писать то, чего не понимаешь. Это бред какой то.
Лучше не программировать тогда. Радианы в школе проходят.
Вот синус:
PIdiv180: double = (PI / 180);
lpSin := Sin(Angle * PIdiv180);
>И давно ли Делфи7 выполняет Sin() при помощи SSE?)))
Давно. Где то с 2005-2009-й версии. В Д7 нету. Там ФПУ. Но можно байт-коды забить в ASM.
SSE - быстрее чем ФПУ из-за отсутствия подготовки и типа double.
Если Extended не нужен - то SSE -лучше всего и быстрее.
-
> плавающие и чо.
Дак вот чё:
procedure TForm1.Button1Click(Sender: TObject);
const pi2: Double = PI*2;
var x: Double;
begin
x:=-217.21;
x:=x mod pi2;
end;
[Error] Unit1.pas(75325): Operator not applicable to this operand type
Вполне ожидаемо. А мне проще сделать таблицу от -300 до 300 чем непонятно как подгонять радианы, ломать голову на чего их домножать там.