Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdint.h>
- namespace rational
- {
- namespace detail
- {
- /// вычисление НОД
- 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;
- };
- }
- using detail::gcd;
- }
- namespace rational
- {
- namespace detail
- {
- template <int64_t A, int64_t B>
- struct rational_t;
- 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 <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;
- };
- template <class R>
- struct reduce
- {
- typedef typename reduce_accurate<require_reduce<R>::value, R>::type type;
- };
- }
- using detail::reduce;
- }
- namespace rational
- {
- namespace detail
- {
- 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; }
- };
- 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 <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;
- };
- }
- using detail::rational_t;
- using detail::plus;
- using detail::minus;
- using detail::mult;
- using detail::divide;
- using detail::less;
- }
- #define RATIONAL(A1, A2) rational::rational_t<(int)(A1##A2), rational::detail::pow<10, sizeof(#A2)-1>::value>
- namespace rational
- {
- namespace detail
- {
- 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;
- };
- 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;
- };
- }
- using detail::sqrt;
- }
- #include <iostream>
- 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;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement