Полезное для программистов:

Фриланс
Новости
Статьи
   
Рубрики:


Синус и Косинус

Поиск:
На интервале [0,pi/8] вычисляется тангенс, для чего используется цепная дробь:
 tan(x) = x/(1-x2/(3-x2/(5-x2/(7-x2/...)))). 
 Для single precision требуется 4 итерации, для double - 6-7. Затем синус и косинус на интервале [0,pi/4] вычисляются через тангенс половинного аргумента: 
 sin(x1)=2*t/(1+t2), nbsp;   cos(x1)=(1-t2)/(1+t2)
 Затем, применяя алгоритм к x2=(pi/2-x1), можно расширить интервал до  [0,pi/2]. Применяя известные формулы тригонометрии, интервал расширяется до полного цикла: [-pi,pi]. Дальнейшее расширение достаточно тривиально, но здесь не сделано -- сами пробуйте если хотите.Имеется альтернативный подход, требующий большего числа операций, но удобный при представлении аргумента в виде fixed point. В этом случае алгоритм связан с проведением серии комплексных умножений на табличные данные. Будет приведен в дальнейшем -- ждите добавления. Ниже приведена программа, реализующая вычисление синуса и косинуса через тангенс.

Код

/* Sine and cosine without mathematic library. Optimized for floating
   point single precision.
   Copyright (c) Nikitin V.F. 2000

   Calculate sine and cosine within [0, PI/4]:
   void _Sico(float arg,float *sine,float *cosi);

   Calculate sine and cosine within [0, PI/2]:
   void Sico(float arg,float *sine,float *cosi);

   Calculate sine and cosine within one period [-PI, PI]:
   void Sico1p(float arg,float *sine,float *cosi);

   No argument domain check is performed: insert yourself.
*/

#define M_PI ((float)3.141592653589793)
#define M_PI4 (M_PI*0.25F)
#define M_PI2 (M_PI*0.5F)

/* sine and cosine within 0-PI/4. MFRAC=4 optimized for single precision */
#define MFRAC 4    
void _Sico(float arg, float *sine, float *cosi) {
  int n,n2;
  float arg2,t;
  /* calculate tangent by continuous fraction */
  t=0.; arg*=0.5F; arg2=arg*arg; n=MFRAC-1; n2=(n<<1)+1;
  for(;n>=0;n--) {
    if(n>0) t=arg2/(n2-t);
    else t=arg/(1.F-t);
    n2--; n2--;
  }
  /* sine and cosine */
  arg=t*t; arg2=arg+1.F; arg2=1.F/arg2;
  *sine=t*arg2; *sine+=(*sine);
  *cosi=1.F-arg; *cosi*=arg2;
}

/* argument 0-PI/2 */
void Sico(float arg, float *sine, float *cosi) {
  if(arg<=M_PI4) _Sico(arg,sine,cosi);
  else _Sico(M_PI2-arg,cosi,sine);
}

/* first period: -PI<=arg<=PI */
void Sico1p(float arg, float *sine, float *cosi) {
  int s=0;
  if(arg<0.F) {arg=-arg;s=1;}
  if(arg<=M_PI2) Sico(arg,sine,cosi);
  else {
    Sico(arg-M_PI2,cosi,sine);
    *cosi=-(*cosi);
  }
  if(s) *sine=-(*sine);
}







Просмотров: 12096

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную