fork download
  1. /*
  2.  * sincos_table.c: 三角関数をテーブル引きにして高速化
  3.  *
  4.  * [2002/08/16] OSHIRO Naoki. <oshiro@mibai.tec.u-ryukyu.ac.jp>
  5.  *
  6.  */
  7.  
  8. /* compile: gcc -O3 -c sincos_table.c */
  9. /* 最適化オプション(-O3 など)を必ず付けること! */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <math.h>
  14.  
  15. static int SinCos_num=-1;
  16. static double *SinCos_table=NULL;
  17.  
  18. /*#include "sincos_table.h"*/
  19.  
  20. /* SinCos_init: 90度分の cos() テーブルを作成する */
  21. void SinCos_init(int num)
  22. {
  23. int i;
  24.  
  25. if (num<=0) {
  26. fprintf(stderr, "SinCos: specified init number error (%d).\n", num);
  27. exit(1);
  28. }
  29. SinCos_table=malloc(sizeof(double)*num);
  30. if (SinCos_table==NULL) {
  31. fprintf(stderr, "SinCos: not enough memory.\n");
  32. exit(1);
  33. }
  34. SinCos_num=num;
  35. for (i=0; i<num; i++) {
  36. SinCos_table[i]=cos(i*M_PI/2/num);
  37. }
  38. }
  39.  
  40. /* SinCos テーブル範囲を毎回チェック.定義すると安全だが20倍は遅くなる */
  41. #undef SINCOS_CHECK
  42.  
  43. /* Cos() 関数 */
  44. double Cos(double x)
  45. {
  46. double sign=1;
  47. int i;
  48.  
  49. #ifdef SINCOS_CHECK
  50. if (SinCos_num<=0) {
  51. fprintf(stderr, "Not initialize SinCos_table.\n");
  52. exit(1);
  53. }
  54. #endif
  55. if (x<0) x=-x; /* cos(x)=cos(-x) */
  56. x/=M_PI;
  57. x=(x-(int)(x/2)*2); /* cos(x)=cos(x+2*PI) */
  58. if (x>1) x=2-x; /* cos(x)=cos(x-PI) */
  59. if (x>.5) {x=1-x; sign=-1;} /* -cos(x)=cos(PI-x) */
  60. i=(int)(x*2*SinCos_num);
  61. #ifdef SINCOS_CHECK
  62. if (i<0 || i>=SinCos_num) {
  63. fprintf(stderr, "SinCos: specified number out of range (%d).\n", i);
  64. exit(1);
  65. }
  66. #endif
  67. return (sign*SinCos_table[i]);
  68. }
  69.  
  70.  
  71. /************************************************************/
  72. /*#ifdef SINCOS_TABLE_TEST*/
  73. #include <time.h>
  74.  
  75. int main(void)
  76. {
  77. int i, j, num;
  78. clock_t t;
  79. double x = 0;
  80.  
  81. /* SinCosテーブル初期化 */
  82. /* 分割数と誤差の目安: 分割数 1e+X, 誤差 1e-(X+1) */
  83. num=1e+5;
  84. SinCos_init(num);
  85. printf("SinCos_Table:%d\n", num);
  86. #if 0
  87. /* 0.01 [rad] 刻みで sin() と Sin(), cos() と Cos() の精度比較をする */
  88. printf("x,sin(),Sin(),sin()-Sin(x)\n");
  89. for (x=-10; x<10; x+=0.01) {
  90. printf("%f %f %f %+e\n", x, sin(x), Sin(x), sin(x)-Sin(x));
  91. }
  92. printf("\n");
  93. printf("x,cos(),Cos(),cos()-Cos(x)\n");
  94. for (x=-10; x<10; x+=0.01) {
  95. printf("%f %f %f %+e\n", x, cos(x), Cos(x), cos(x)-Cos(x));
  96. }
  97. printf("\n");
  98. #endif
  99.  
  100. /* cos() と Cos() の速度比較 */
  101. printf("Time benchmark: cos(), Cos()\n");
  102. /* cos() */
  103. t=clock();
  104. for (i=0; i<50000; i++)
  105. for (j=0; j<10000; j++)
  106. x += cos(.1);
  107. printf("cos:%.2fsec\n", (double)(clock()-t) / CLOCKS_PER_SEC);
  108.  
  109. /* Cos() */
  110. t=clock();
  111. for (i=0; i<50000; i++)
  112. for (j=0; j<10000; j++)
  113. x += Cos(.1);
  114. printf("Cos:%.2fsec\n", (double)(clock()-t) / CLOCKS_PER_SEC);
  115. return (int)x;
  116. }
  117. /*#endif /* SINCOS_TABLE_TEST */
  118.  
Runtime error #stdin #stdout 2.03s 2460KB
stdin
Standard input is empty
stdout
SinCos_Table:100000
Time benchmark: cos(), Cos()
cos:0.91sec
Cos:1.09sec