fork download
  1. #include <iostream>
  2. #include <cmath>
  3. #include <vector>
  4. #include <iterator>
  5. #include <numeric>
  6. #include <algorithm>
  7. #include <iomanip>
  8.  
  9. long double factorial(int i)
  10. {
  11. long double fac = 1.0;
  12.  
  13. for (; i > 0; i--)
  14. fac *= i;
  15.  
  16. return fac;
  17. }
  18.  
  19. struct Gen {
  20. Gen(int i, double rad) : n(i), r(rad) {}
  21. double operator()() {
  22. double x = std::pow(r, 2 * n + 1);
  23. long double y = factorial(2 * n + 1);
  24.  
  25. return static_cast<double>(x / y * ((n++ % 2 == 0) ? 1.0 : -1.0));
  26. }
  27. private:
  28. int n;
  29. double r;
  30. };
  31.  
  32. int main(void)
  33. {
  34. std::vector<double> vd;
  35. double rad, sinrad;
  36. int n;
  37.  
  38. // std::cout << "input rad = ";
  39. // std::cin >> rad;
  40. // std::cout << "input N = ";
  41. // std::cin >> n;
  42.  
  43. rad = M_PI / 3;
  44. n = 500;
  45.  
  46. // radの正規化
  47. if (rad > 2 * M_PI)
  48. rad -= 2.0 * M_PI * static_cast<int>(rad / (2.0 * M_PI));
  49. else if (rad < 0.0)
  50. rad += 2.0 * M_PI * static_cast<int>(std::fabs(rad) / (2.0 * M_PI) + 1.0);
  51.  
  52. std::generate_n(std::back_inserter(vd), n, Gen(0, rad));
  53. sinrad = std::accumulate(vd.begin(), vd.end(), 0.0);
  54.  
  55. std::cout << std::setprecision(15);
  56.  
  57. std::cout << "sin(rad) = " << std::sin(rad);
  58. std::cout << "\ntaylor sin(rad) = " << sinrad << std::endl;;
  59.  
  60. // 逆順に足して積み残し誤差を確認してみる
  61. sinrad = std::accumulate(vd.rbegin(), vd.rend(), 0.0);
  62.  
  63. std::cout << "reverse sum";
  64. std::cout << "\nsin(rad) = " << std::sin(rad);
  65. std::cout << "\ntaylor sin(rad) = " << sinrad << std::endl;;
  66.  
  67. }
  68.  
Success #stdin #stdout 0.01s 2812KB
stdin
Standard input is empty
stdout
sin(rad)        = 0.866025403784439
taylor sin(rad) = 0.866025403784438
reverse sum
sin(rad)        = 0.866025403784439
taylor sin(rad) = 0.866025403784439