asvp
> http://www.gamedev.ru/code/forum/?id=93064
Я только предлагаю альтернативу :D
Да и тут до 90 градусов только,а не убер-быстрая-мега-функция :D
Кстате я помню что с небольшой погрешностью реализовывал более быструю функцию чем стандартная)
Если найду скину)
Alior
> Да и тут до 90 градусов только,а не убер-быстрая-мега-функция :D
Любой угол от -2пи до +2пи.
попробовал код этой подсказки
почему-то у меня выходные переменные не получают результат. что в них было до вызова, то и остаётся.
тестил так:
float a = 0.23;
float c = 0;
float s = 0;
sincos(a,s,c);
cout << sinf(a)<<" "<<cosf(a)<<" - "<<s<<" "<<c<<"\n";
син и кос пишут числа, а c и s остаются нулями. если я не инициализировал c и s, то они остаются неинициализированными (левые числа).
ещё у меня супер дупер древняя msvc 2003
от каких-нибудь настроек компиляции может не работать?
------
вот так заработала:
void sincos(float a, float* s, float* c) { _asm { fld a fsincos mov ebx,[c] fstp dword ptr [ebx] mov ebx,[s] fstp dword ptr [ebx] } }
но на целых 2 инструкции больше)
Приведение к периоду занимает почти столько же, как и вычисление синуса/косинуса.
>Приведение к периоду
это что?
Mr F
> > Приведение к периоду
> это что?
Есть такая операция в сопроцессоре.
Может использоваться для тригонометрии, чтобы произвольный аргумент загнать в требуемые рамки. Встроенные в сопроцессор операции сами выполняют приведение к периоду, а для своих реализаций как правило это требуется делать дополнительно. Затраты времени на приведение к периоду ликвидируют все преимущества в скорости своих методик расчета.
Используйте
__declspec(naked) void sincos(float a, float &s, float &c) { _asm { fld dword ptr[esp + 4]; fsincos; mov eax, [esp + 8]; // s mov ecx, [esp + 12]; // c fstp dword ptr[ecx]; fstp dword ptr[eax]; retn; } }
Alior
> Синус с достаточной точность можно вычислить вообще sin(x)=x-((x^3)/6)
> Причем x>=0 и x<=1.57
> Но так можно вычислить углы только до 90 градусов)
> Если хочется дальше надо продолжать ряд Тейлора)
> Но добавив пару евристик можно найти синус любого угла)
> С косинусами почти тоже самое :)[/quote]
Ряд Маклорена
f(x) = sin(x) f(x) = sin(x) f(0) = sin(0) = 0 f'(x) = cos(x) f'(0) = cos(0) = 1 f''(x) = -sin(x) f''(0) = -sin(0) = 0 f'''(x) = -cos(x) f'''(0) = -cos(0) = -1 f''''(x) = sin(x) f''''(0) = sin(0) = 0 f'''''(x) = cos(x) f'''''(0) = cos(0) = 1 sin(x) = f(0) + f'(0)x + (f''(0) / 2!)x^2 + (f'''(0) / 3!)x^3 + (f''''(0) / 4!)x^4 + (f'''''(0) / 5!)x^5 sin(x) = 0 + (1)x + (0/2!)x^2 + (-1/3!)x^3 + (0/4!)x^4 + (1/5!)x^5 sin(x) = x - (1/3!)x^3 + (1/5!)x^5 sin(x) = x - x^3/6 + x^5/120
Стандартный fsincos по документации и в реале дает не меньше 120 тактов на всех процессорах. Полином/ряд с той же точностью на Core iX c SSE оптимизацией даст не больше 36 тактов. Для ряда Тейлора хватает 16 коэффициентов - 4 "векторных" умножения для SSE, 2 для AVX.
Тема в архиве.