synaps/arithm/hdwi.h

00001 #ifndef SYNAPS_NUMERICS_HDWI_H
00002 #define SYNAPS_NUMERICS_HDWI_H
00003 
00004 #include <synaps/init.h> 
00005 
00006 __BEGIN_NAMESPACE_SYNAPS
00007 
00008 namespace numerics
00009 {
00010   template< class T >
00011   struct is_rounded              { static const bool result = false; typedef Type::false_t result_t; };
00012   template< >
00013   struct is_rounded<float>       { static const bool result = true;  typedef Type::true_t  result_t; };
00014   template< > 
00015   struct is_rounded<double>      { static const bool result = true;  typedef Type::true_t  result_t; };
00016   template< >
00017   struct is_rounded<long double> { static const bool result = true;  typedef Type::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 __END_NAMESPACE_SYNAPS
00122 
00123 #endif

SYNAPS DOCUMENTATION
logo