00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef SYNAPS_ARITHM_POW_H
00010 #define SYNAPS_ARITHM_POW_H
00011
00012 #include <synaps/init.h>
00013 #include <synaps/arithm/traits.h>
00014 #include <synaps/arithm/inv.h>
00015
00016 __BEGIN_NAMESPACE_SYNAPS
00017
00018
00019 template<class T>
00020 T pow(const T& a, int i, const type::false_t& val)
00021 {
00022 assert(i>=0);
00023 if(i == 1) return a;
00024 if(i > 0)
00025 {
00026 if (a == T(1)) return a;
00027 if (a == T(-1)) return (i % 2 == 0) ? T(1) : T(-1);
00028 T y(a);
00029 T z(1);
00030 unsigned int n = i;
00031 unsigned int m;
00032 while (n > 0) {
00033 m = n / 2;
00034 if (n %2 )
00035 {
00036 z *= y;
00037 }
00038 y = y * y;
00039 n = m;
00040 }
00041 return z;
00042 }
00043 return T(1);
00044 }
00045
00046
00048 template<class C> inline
00049 C pow( const C& a, int i, const type::true_t& val)
00050 {
00051 typedef C rat_t;
00052 return (i>0? rat_t(pow(a,i,type::false_t())): (i==0? rat_t(1): rat_t(rat_t(1)/pow(a,-i,type::false_t()))));
00053 }
00054
00056 template<class X> inline
00057 X pow(const X& a, int i)
00058 {
00059 typedef typename arithm::isfield<X>::T is_field_t;
00060 return pow(a,i, is_field_t());
00061 }
00062
00063 __END_NAMESPACE_SYNAPS
00064 #endif // SYNAPS_ARITHM_POW_H
00065