#include <iostream>
#include <cmath>
#include <vector>
#include <iterator>
#include <numeric>
#include <algorithm>
#include <iomanip>
long double factorial(int i)
{
long double fac = 1.0;
for (; i > 0; i--)
fac *= i;
return fac;
}
struct Gen {
Gen(int i, double rad) : n(i), r(rad) {}
double operator()() {
double x = std::pow(r, 2 * n + 1);
long double y = factorial(2 * n + 1);
return static_cast<double>(x / y * ((n++ % 2 == 0) ? 1.0 : -1.0));
}
private:
int n;
double r;
};
int main(void)
{
std::vector<double> vd;
double rad, sinrad;
int n;
// std::cout << "input rad = ";
// std::cin >> rad;
// std::cout << "input N = ";
// std::cin >> n;
rad = M_PI / 3;
n = 500;
// radの正規化
if (rad > 2 * M_PI)
rad -= 2.0 * M_PI * static_cast<int>(rad / (2.0 * M_PI));
else if (rad < 0.0)
rad += 2.0 * M_PI * static_cast<int>(std::fabs(rad) / (2.0 * M_PI) + 1.0);
std::generate_n(std::back_inserter(vd), n, Gen(0, rad));
sinrad = std::accumulate(vd.begin(), vd.end(), 0.0);
std::cout << std::setprecision(15);
std::cout << "sin(rad) = " << std::sin(rad);
std::cout << "\ntaylor sin(rad) = " << sinrad << std::endl;;
// 逆順に足して積み残し誤差を確認してみる
sinrad = std::accumulate(vd.rbegin(), vd.rend(), 0.0);
std::cout << "reverse sum";
std::cout << "\nsin(rad) = " << std::sin(rad);
std::cout << "\ntaylor sin(rad) = " << sinrad << std::endl;;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxpdGVyYXRvcj4KI2luY2x1ZGUgPG51bWVyaWM+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxpb21hbmlwPgoKbG9uZyBkb3VibGUgZmFjdG9yaWFsKGludCBpKQp7CiAgbG9uZyBkb3VibGUgZmFjID0gMS4wOwogIAogIGZvciAoOyBpID4gMDsgaS0tKQogICAgZmFjICo9IGk7CiAgCiAgcmV0dXJuIGZhYzsKfQoKc3RydWN0IEdlbiB7CiAgR2VuKGludCBpLCBkb3VibGUgcmFkKSA6IG4oaSksIHIocmFkKSB7fQogIGRvdWJsZSBvcGVyYXRvcigpKCkgewogICAgZG91YmxlIHggPSBzdGQ6OnBvdyhyLCAyICogbiArIDEpOwogICAgbG9uZyBkb3VibGUgeSA9IGZhY3RvcmlhbCgyICogbiArIDEpOwogICAgCiAgICByZXR1cm4gc3RhdGljX2Nhc3Q8ZG91YmxlPih4IC8geSAqICgobisrICUgMiA9PSAwKSA/IDEuMCA6IC0xLjApKTsKICB9CnByaXZhdGU6CiAgaW50IG47CiAgZG91YmxlIHI7Cn07CgppbnQgbWFpbih2b2lkKQp7CiAgc3RkOjp2ZWN0b3I8ZG91YmxlPiB2ZDsKICBkb3VibGUgcmFkLCBzaW5yYWQ7CiAgaW50IG47CiAgCi8vICBzdGQ6OmNvdXQgPDwgImlucHV0IHJhZCA9ICI7Ci8vICBzdGQ6OmNpbiA+PiByYWQ7Ci8vICBzdGQ6OmNvdXQgPDwgImlucHV0IE4gPSAiOwovLyAgc3RkOjpjaW4gPj4gbjsKICAKICByYWQgPSBNX1BJIC8gMzsKICBuID0gNTAwOwogIAogIC8vIHJhZOOBruato+imj+WMlgogIGlmIChyYWQgPiAyICogTV9QSSkKICAgIHJhZCAtPSAyLjAgKiBNX1BJICogc3RhdGljX2Nhc3Q8aW50PihyYWQgLyAoMi4wICogTV9QSSkpOwogIGVsc2UgaWYgKHJhZCA8IDAuMCkKICAgIHJhZCArPSAyLjAgKiBNX1BJICogc3RhdGljX2Nhc3Q8aW50PihzdGQ6OmZhYnMocmFkKSAvICgyLjAgKiBNX1BJKSArIDEuMCk7CgogIHN0ZDo6Z2VuZXJhdGVfbihzdGQ6OmJhY2tfaW5zZXJ0ZXIodmQpLCBuLCBHZW4oMCwgcmFkKSk7CiAgc2lucmFkID0gc3RkOjphY2N1bXVsYXRlKHZkLmJlZ2luKCksIHZkLmVuZCgpLCAwLjApOwogIAogIHN0ZDo6Y291dCA8PCBzdGQ6OnNldHByZWNpc2lvbigxNSk7CiAgCiAgc3RkOjpjb3V0IDw8ICJzaW4ocmFkKSAgICAgICAgPSAiIDw8IHN0ZDo6c2luKHJhZCk7CiAgc3RkOjpjb3V0IDw8ICJcbnRheWxvciBzaW4ocmFkKSA9ICIgPDwgc2lucmFkIDw8IHN0ZDo6ZW5kbDs7CgogIC8vIOmAhumghuOBq+i2s+OBl+OBpuepjeOBv+aui+OBl+iqpOW3ruOCkueiuuiqjeOBl+OBpuOBv+OCiwogIHNpbnJhZCA9IHN0ZDo6YWNjdW11bGF0ZSh2ZC5yYmVnaW4oKSwgdmQucmVuZCgpLCAwLjApOwogIAogIHN0ZDo6Y291dCA8PCAicmV2ZXJzZSBzdW0iOwogIHN0ZDo6Y291dCA8PCAiXG5zaW4ocmFkKSAgICAgICAgPSAiIDw8IHN0ZDo6c2luKHJhZCk7CiAgc3RkOjpjb3V0IDw8ICJcbnRheWxvciBzaW4ocmFkKSA9ICIgPDwgc2lucmFkIDw8IHN0ZDo6ZW5kbDs7Cgp9Cg==