typedef RATIONAL(2,0) x; typedef sqrt<x>::type result;
std::cout << result::get() << std::endl;
1.41421356 template <int64_t A, int64_t B> struct rational_t { const static int64_t a = A, b = B; static double get() { return (double)a/b; } };
rational_t<3,2> -> 3/2 rational_t<56,10> -> 56/10 = 5.6 rational_t<3,100> -> 3/100 = 0.03
#define RATIONAL(A1, A2) rational_t<(int)(A1##A2), pow<10, sizeof(#A2)-1>::value>
1) A1 ## A2 sticks together two arguments in 1234 2) sizeof (# A2) -1 = sizeof ("34") - 1 = 3 - 1 = 2 3) pow <10, 2> :: value = 10 to the power of 2 = 100
template <int V, unsigned D> struct pow { const static int value = V * pow<V, D - 1>::value; }; template <int V> struct pow<V, 0> { const static int value = 1; };
template <class R1, class R2> struct plus { typedef rational_t<R1::a * R2::b + R2::a * R1::b, R1::b * R2::b> type; };
template <class R1, class R2> struct plus { typedef rational_t<R1::a * R2::b + R2::a * R1::b, R1::b * R2::b> type1; typedef typename reduce<type1>::type type; };
template <class R1, class R2> struct minus { typedef rational_t<R1::a * R2::b - R2::a * R1::b, R1::b * R2::b> type1; typedef typename reduce<type1>::type type; }; template <class R1, class R2> struct mult { typedef rational_t<R1::a * R2::a, R1::b * R2::b> type1; typedef typename reduce<type1>::type type; }; template <class R1, class R2> struct divide { typedef rational_t<R1::a * R2::b, R1::b * R2::a> type1; typedef typename reduce<type1>::type type; };
template <class R1, class R2> struct less { static const bool value = (R1::a * R2::b - R2::a * R1::b) < 0; };
template <class R> struct require_reduce { const static int64_t max = (1ll<<31); const static bool value = (R::a >= max) || (R::b >= max); };
template <bool, class R> struct reduce_accurate;
template <bool, class R> struct reduce_inaccurate { typedef rational_t<(R::a >> 1), (R::b >> 1)> type_; typedef typename reduce_accurate<require_reduce<type_>::value, type_>::type type; };
template <class R> struct reduce_inaccurate<false, R> { typedef R type; };
template <int64_t m, int64_t n> struct gcd; template <int64_t a> struct gcd<a, 0> { static const int64_t value = a; }; template <int64_t a, int64_t b> struct gcd { static const int64_t value = gcd<b, a % b>::value; };
template <bool, class R> struct reduce_accurate { template <bool, class R> struct reduce_accurate { const static int64_t new_a = R::a / gcd<R::a, R::b>::value; const static int64_t new_b = R::b / gcd<R::a, R::b>::value; typedef rational_t<new_a, new_b> new_type; typedef typename reduce_inaccurate<require_reduce<new_type>::value, new_type>::type type; }; };
template <class R> struct reduce_accurate<false, R> { typedef typename reduce_inaccurate<require_reduce<R>::value, R>::type type; };
: sqrt_eval(p, res, x) { t1 = x/res t2 = res+t1 tmp = t2/2 if (p-1 == 0) return tmp; return sqrt_eval(p-1, tmp, x) }
template <int64_t p, class res, class x> struct sqrt_eval { typedef typename divide<x, res>::type t1; typedef typename plus<res, t1>::type t2; typedef typename divide<t2, rational_t<2,1> >::type tmp; typedef typename sqrt_eval<p-1, tmp, x>::type type; }; template <class res, class x> struct sqrt_eval<0, res, x> { typedef res type; };
sqrt(x) { res = (x + 1)/2 return sqrt_eval(15, res, x) }
template <class x> struct sqrt { typedef typename divide< typename plus<x, rational_t<1,1> >::type, rational_t<2,1> >::type res; typedef typename sqrt_eval<15, res, x>::type type; }; template <int64_t a> struct sqrt< rational_t<0, a> > { static const int64_t value = 0; };
#include <iostream> #include "rational_algo.hpp" int main() { std::cout.precision(15); const double s = rational::sqrt<RATIONAL(2,0)>::type::get(); std::cout << s << std::endl; std::cout << 2-s*s << std::endl; return 0; }
Source: https://habr.com/ru/post/124963/
All Articles