Advertisement
Guest User

rational example

a guest
Aug 2nd, 2011
409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.36 KB | None | 0 0
  1. #include <stdint.h>
  2.  
  3. namespace rational
  4. {
  5.   namespace detail
  6.   {
  7.     /// вычисление НОД
  8.     template <int64_t m, int64_t n>
  9.     struct gcd;
  10.     template <int64_t a>
  11.     struct gcd<a, 0>
  12.     {
  13.       static const int64_t value = a;
  14.     };
  15.     template <int64_t a, int64_t b>
  16.     struct gcd
  17.     {
  18.       static const int64_t value = gcd<b, a % b>::value;
  19.     };
  20.   }
  21.  
  22.   using detail::gcd;
  23. }
  24.  
  25. namespace rational
  26. {
  27.   namespace detail
  28.   {
  29.     template <int64_t A, int64_t B>
  30.     struct rational_t;
  31.  
  32.     template <class R>
  33.     struct require_reduce
  34.     {
  35.       const static int64_t max = (1ll<<31);
  36.       const static bool value = (R::a >= max) || (R::b >= max);
  37.     };
  38.  
  39.     template <bool, class R>
  40.     struct reduce_accurate;
  41.  
  42.     template <bool, class R>
  43.     struct reduce_inaccurate
  44.     {
  45.       typedef rational_t<(R::a >> 1), (R::b >> 1)> type_;
  46.       typedef typename reduce_accurate<require_reduce<type_>::value, type_>::type type;
  47.     };
  48.  
  49.     template <class R>
  50.     struct reduce_inaccurate<false, R>
  51.     {
  52.       typedef R type;
  53.     };
  54.  
  55.     template <bool, class R>
  56.     struct reduce_accurate
  57.     {
  58.       const static int64_t new_a = R::a / gcd<R::a, R::b>::value;
  59.       const static int64_t new_b = R::b / gcd<R::a, R::b>::value;
  60.  
  61.       typedef rational_t<new_a, new_b> new_type;
  62.       typedef typename reduce_inaccurate<require_reduce<new_type>::value, new_type>::type type;
  63.     };
  64.  
  65.     template <class R>
  66.     struct reduce_accurate<false, R>
  67.     {
  68.       typedef typename reduce_inaccurate<require_reduce<R>::value, R>::type type;
  69.     };
  70.  
  71.     template <class R>
  72.     struct reduce
  73.     {
  74.       typedef typename reduce_accurate<require_reduce<R>::value, R>::type type;
  75.     };
  76.   }
  77.  
  78.   using detail::reduce;
  79. }
  80.  
  81. namespace rational
  82. {
  83.   namespace detail
  84.   {
  85.     template <int64_t A, int64_t B>
  86.     struct rational_t
  87.     {
  88.       const static int64_t a = A, b = B;
  89.       static double get() { return (double)a/b; }
  90.     };
  91.  
  92.     template <class R1, class R2>
  93.     struct plus
  94.     {
  95.       typedef rational_t<R1::a * R2::b + R2::a * R1::b, R1::b * R2::b> type1;
  96.       typedef typename reduce<type1>::type type;
  97.     };
  98.  
  99.     template <class R1, class R2>
  100.     struct minus
  101.     {
  102.       typedef rational_t<R1::a * R2::b - R2::a * R1::b, R1::b * R2::b> type1;
  103.       typedef typename reduce<type1>::type type;
  104.     };
  105.  
  106.     template <class R1, class R2>
  107.     struct mult
  108.     {
  109.       typedef rational_t<R1::a * R2::a, R1::b * R2::b> type1;
  110.       typedef typename reduce<type1>::type type;
  111.     };
  112.  
  113.     template <class R1, class R2>
  114.     struct divide
  115.     {
  116.       typedef rational_t<R1::a * R2::b, R1::b * R2::a> type1;
  117.       typedef typename reduce<type1>::type type;
  118.     };
  119.  
  120.     template <class R1, class R2>
  121.     struct less
  122.     {
  123.       static const bool value = (R1::a * R2::b - R2::a * R1::b) < 0;
  124.     };
  125.  
  126.     template <int V, unsigned D>
  127.     struct pow
  128.     {
  129.       const static int value = V * pow<V, D - 1>::value;
  130.     };
  131.     template <int V>
  132.     struct pow<V, 0>
  133.     {
  134.       const static int value = 1;
  135.     };
  136.   }
  137.  
  138.   using detail::rational_t;
  139.   using detail::plus;
  140.   using detail::minus;
  141.   using detail::mult;
  142.   using detail::divide;  
  143.   using detail::less;
  144. }
  145.  
  146. #define RATIONAL(A1, A2) rational::rational_t<(int)(A1##A2), rational::detail::pow<10, sizeof(#A2)-1>::value>
  147.  
  148. namespace rational
  149. {
  150.   namespace detail
  151.   {
  152.     template <int64_t p, class res, class x>
  153.     struct sqrt_eval
  154.     {
  155.       typedef typename divide<x, res>::type t1;
  156.       typedef typename plus<res, t1>::type t2;
  157.       typedef typename divide<t2, rational_t<2,1> >::type tmp;
  158.       typedef typename sqrt_eval<p-1, tmp, x>::type type;
  159.     };
  160.  
  161.     template <class res, class x>
  162.     struct sqrt_eval<0, res, x>
  163.     {
  164.       typedef res type;
  165.     };
  166.  
  167.     template <class x>
  168.     struct sqrt
  169.     {
  170.       typedef typename divide< typename plus<x, rational_t<1,1> >::type, rational_t<2,1> >::type res;
  171.       typedef typename sqrt_eval<15, res, x>::type type;
  172.     };
  173.  
  174.     template <int64_t a>
  175.     struct sqrt< rational_t<0, a> >
  176.     {
  177.       static const int64_t value = 0;
  178.     };
  179.   }
  180.  
  181.   using detail::sqrt;
  182. }
  183.  
  184. #include <iostream>
  185.  
  186. int main()
  187. {
  188.   std::cout.precision(15);
  189.   const double s = rational::sqrt<RATIONAL(2,0)>::type::get();
  190.   std::cout << s << std::endl;
  191.   std::cout << 2-s*s << std::endl;
  192.  
  193.   return 0;
  194. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement