realroot_doc 0.1.1
|
00001 #ifndef realroot_NUMERICS_HDWI_H 00002 #define realroot_NUMERICS_HDWI_H 00003 00004 #include <realroot/texp.hpp> 00005 00006 namespace mmx { 00007 00008 namespace numerics 00009 { 00010 template< class T > 00011 struct is_rounded { static const bool result = false; typedef texp::false_t result_t; }; 00012 template< > 00013 struct is_rounded<float> { static const bool result = true; typedef texp::true_t result_t; }; 00014 template< > 00015 struct is_rounded<double> { static const bool result = true; typedef texp::true_t result_t; }; 00016 template< > 00017 struct is_rounded<long double> { static const bool result = true; typedef texp::true_t result_t; }; 00018 00019 template< class T > 00020 struct bit_resolution 00021 { static const int nbit = sizeof(unsigned)*8*3; }; 00022 template<> 00023 struct bit_resolution<double> 00024 { static const int nbit = sizeof(double)*8; }; 00025 template<> 00026 struct bit_resolution<long double> { static const int nbit = sizeof(long double); }; 00027 00028 template< class T > 00029 unsigned bitprec( const T& e, const T& l = T(1.0) ) 00030 { 00031 T tmp(l); 00032 unsigned b = 2; 00033 while ( tmp > e ) { tmp/=2; b++; }; 00034 return b; 00035 }; 00036 00037 template<typename hdwi, unsigned n> 00038 struct hdwimax { static const hdwi result; }; 00039 template<typename T,unsigned n> 00040 const T hdwimax<T,n>::result((hdwimax<T,n-1>::result<<1)|1); 00041 template<typename hdwi> 00042 struct hdwimax<hdwi,0> { static const hdwi result; }; 00043 template<typename T> const T hdwimax<T,0>::result(0); 00044 template< class T > 00045 struct hdwintp { static const bool result = false; }; 00046 template< class hardware_int > 00047 struct hdwi 00048 { 00049 00050 typedef hardware_int hdw_int; 00051 //enum { nbit = sizeof(hardware_int)*8 }; 00052 static const unsigned nbit = sizeof(hardware_int)*8; 00053 static const hardware_int nmax; 00054 static hdw_int reverse( hdw_int a ) 00055 { 00056 hdw_int res = 0; 00057 for ( unsigned i = 0; i < nbit; i ++ ) 00058 { 00059 res <<= 1; 00060 res |= a & 1; 00061 a >>= 1; 00062 }; 00063 return res; 00064 }; 00065 static void reverse( unsigned h, hdw_int& a) 00066 { 00067 unsigned i; 00068 hdw_int c; 00069 c = 0; 00070 for ( i = 0; i < h; i ++ ) 00071 { 00072 c <<= 1; 00073 c |= a&1; 00074 a >>= 1; 00075 }; 00076 a = c; 00077 }; 00078 }; 00079 template<class T> const T hdwi<T>::nmax( hdwimax<T,sizeof(T)*8>::result ); 00080 00081 template<class unsigned_t> // a faire = sar 00082 void sal( unsigned_t& a, unsigned n ) 00083 { 00084 assert(n<=hdwi<unsigned_t>::nbit); 00085 if ( a & 1 ) 00086 { 00087 unsigned_t msk(hdwi<unsigned_t>::nmax); 00088 msk >>= (hdwi<unsigned_t>::nbit-n); 00089 a <<= n; 00090 a |= msk; 00091 } 00092 else 00093 { 00094 // std::cout << "SAL( " << n << ") \n"; 00095 // std::cout << a << std::endl; 00096 a <<= n; 00097 // std::cout << a << std::endl; 00098 }; 00099 00100 }; 00101 00102 00103 /* met (ha,a) et (hb,b) dans la meme representation 00104 * par un shift arithmetique (SAL), c'est a dire en repetant 00105 * le bit de poids faible. 00106 */ 00107 template<typename unsigned_t> 00108 void hsal( unsigned& ha, unsigned_t& a, unsigned& hb, unsigned_t& b ) 00109 { 00110 if ( ha == hb ) return; // 00111 if ( ha > hb ) 00112 { 00113 sal(b,ha-hb); 00114 hb = ha; 00115 } 00116 else hsal(hb,b,ha,a); 00117 }; 00118 00119 }; 00120 00121 } //namespace mmx 00122 00123 #endif