00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 #ifndef _ARAGELI_powerest_hpp_
00014 #define _ARAGELI_powerest_hpp_
00015 
00016 #include "config.hpp"
00017 #include "exception.hpp"
00018 #include "factory.hpp"
00019 #include "cmp.hpp"
00020 
00021 #include "std_import.hpp"
00022 
00023 
00024 namespace Arageli
00025 {
00026 
00027 
00029 
00030 template <typename T, typename I, typename T_factory>
00031 T power (T a, I n, const T_factory& tfctr);
00032 
00034 template <typename T, typename I>
00035 inline T power (const T& a, const I& n)
00036 { return power(a, n, factory<T>()); }
00037 
00038 
00040 template <typename T, typename I, typename T_factory>
00041 inline T pow2 (I n, const T_factory& tfctr)
00042 {
00043     T res = tfctr.unit();
00044     return res <<= n;
00045 }
00046 
00048 template <typename T, typename I>
00049 inline T pow2 (I n)
00050 {
00051     T res = unit<T>();
00052     return res <<= n;
00053 }
00054 
00055 
00057 template <typename T>
00058 inline T log2 (T x)
00059 { return log(x)/log(2.0l); }
00060 
00061 
00063 
00067 template <typename T1, typename T2, typename Q, typename R>
00068 inline void divide (const T1& a, const T2& b, Q& q, R& r)
00069 {
00070     q = a/b;
00071     r = a%b;
00072     ARAGELI_ASSERT_1(a == b*q + r);
00073 }
00074 
00075 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00094 
00098 template <typename T1, typename T2, typename Q, typename R>
00099 inline void prdivide (const T1& a, const T2& b, Q& q, R& r)
00100 {
00101     divide(a, b, q, r);
00102     
00103     if(is_negative(r))
00104     {
00105         if(is_positive(b)){ --q; r += b; }
00106         else { ++q; r -= b; }
00107     }
00108     
00109     ARAGELI_ASSERT_1(a == b*q + r);
00110     ARAGELI_ASSERT_1(sign(r) >= 0);
00111     ARAGELI_ASSERT_1(is_positive(b) ? r < b : r < -b);
00112 }
00113 
00114 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00133 template <typename T1, typename T2>
00134 inline T1 prquot (const T1& a, const T2& b)
00135 {
00136     T1 q; T2 r;
00137     prdivide(a, b, q, r);
00138     return q;
00139 }
00140 
00142 
00143 
00144 
00145 
00146 
00148 template <typename T1, typename T2>
00149 inline T2 prrem (const T1& a, const T2& b)
00150 {
00151     T1 q; T2 r;
00152     prdivide(a, b, q, r);
00153     return r;
00154 }
00155 
00157 
00158 
00159 
00160 
00161 
00163 template <typename T>
00164 inline T square (const T& a)
00165 { return a*a; }
00166 
00167 
00168 inline int pow (int x, int y)
00169 { return power(x, y); }
00170 
00171 
00173 
00174 
00175 
00176 
00177 
00178 } 
00179 
00180 
00181 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00182     #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_POWEREST
00183     #include "powerest.cpp"
00184     #undef  ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_POWEREST
00185 #endif
00186 
00187 
00188 #endif  //  #ifndef _ARAGELI_powerest_hpp_