CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/L1Trigger/GlobalCaloTrigger/src/L1GctTwosComplement.h

Go to the documentation of this file.
00001 #ifndef L1GCTETTYPES_H
00002 #define L1GCTETTYPES_H
00003 
00004 #include <boost/cstdint.hpp>
00005 #include <ostream>
00006 
00028 template <int nBits>
00029 class L1GctTwosComplement {
00030  public:
00032   L1GctTwosComplement();
00034   L1GctTwosComplement(uint32_t raw);
00036   L1GctTwosComplement(int value);
00038   ~L1GctTwosComplement() { }
00039 
00041   template <int mBits>
00042   L1GctTwosComplement(const L1GctTwosComplement<mBits>& rhs);
00043 
00045   void reset();
00046 
00048   void setRaw(uint32_t raw);
00049 
00051   void setValue(int value);
00052 
00054   void setOverFlow(bool oflow) { m_overFlow = oflow; }
00055 
00057   uint32_t raw() const { return m_data; }
00058 
00060   int value() const;
00061 
00063   bool overFlow() const { return m_overFlow; }
00064 
00066   int size() const { return m_nBits; }
00067 
00069   L1GctTwosComplement operator+ (const L1GctTwosComplement &rhs) const;
00070 
00072   L1GctTwosComplement operator- () const;
00073 
00075   L1GctTwosComplement& operator= (int value);
00076 
00077  private:
00078 
00079   // number of bits (for overflow checking)
00080   int m_nBits;
00081 
00082   // the raw data
00083   uint32_t m_data;
00084 
00085   // the overflow bit
00086   bool m_overFlow;
00087 
00088   static const int MAX_NBITS = 24;
00089   static const int MAX_VALUE = 1<<(MAX_NBITS-1);
00090 
00091   // PRIVATE MEMBER FUNCTION
00092   // function to check overflow
00093   void checkOverFlow(uint32_t rawValue, uint32_t &maskValue, bool &overFlow);
00094 };
00095 
00096 template <int nBits>
00097 std::ostream& operator<<(std::ostream& s, const L1GctTwosComplement<nBits>& data);
00098 
00099 // construct with # bits and set to zero
00100 template <int nBits>
00101 L1GctTwosComplement<nBits>::L1GctTwosComplement() {
00102   m_nBits = nBits>0 && nBits<MAX_NBITS ? nBits : 16 ;
00103   this->reset();
00104 }
00105 
00106 // construct from # bits and raw data 
00107 template <int nBits>
00108 L1GctTwosComplement<nBits>::L1GctTwosComplement(uint32_t raw) {
00109   m_nBits = nBits>0 && nBits<MAX_NBITS ? nBits : 16 ;
00110   m_overFlow = false;
00111   this->setRaw(raw);
00112 }
00113 
00114 // construct from # bits and value
00115 template <int nBits>
00116 L1GctTwosComplement<nBits>::L1GctTwosComplement(int value) {
00117   m_nBits = nBits>0 && nBits<MAX_NBITS ? nBits : 16 ;
00118   m_overFlow = false;
00119   this->setValue(value);
00120 }
00121 
00122 // copy contructor to move data between
00123 // representations with different numbers of bits
00124 template <int nBits>
00125 template <int mBits>
00126 L1GctTwosComplement<nBits>::L1GctTwosComplement(const L1GctTwosComplement<mBits>& rhs) {
00127   m_nBits = nBits>0 && nBits<MAX_NBITS ? nBits : 16 ;
00128   this->setRaw( rhs.raw() );
00129   this->setOverFlow( this->overFlow() || rhs.overFlow() );
00130 }
00131 
00132 // reset value and overflow to zero
00133 template <int nBits>
00134 void L1GctTwosComplement<nBits>::reset() {
00135   m_data = static_cast<uint32_t>(0);
00136   m_overFlow = false;
00137 }
00138 
00139 // set value from uint32_t
00140 template <int nBits>
00141 void L1GctTwosComplement<nBits>::setRaw(uint32_t raw) {
00142   checkOverFlow(raw, m_data, m_overFlow);
00143 }
00144 
00145 // set value from int
00146 template <int nBits>
00147 void L1GctTwosComplement<nBits>::setValue(int value) {
00148   int chkValue, posValue;
00149   uint32_t raw;
00150 
00151   // Make sure we have an integer in the range MAX_NBITS
00152   chkValue = value;
00153   if (chkValue<-MAX_VALUE) { chkValue =  -MAX_VALUE; m_overFlow = true; }
00154   if (chkValue>=MAX_VALUE) { chkValue = MAX_VALUE-1; m_overFlow = true; }
00155 
00156   // Transform negative values to large positive values
00157   posValue = chkValue<0 ? chkValue + (1<<MAX_NBITS) : chkValue ;
00158   raw = static_cast<uint32_t>(posValue);
00159 
00160   // Use the setRaw method to check overflow for our given size nBits
00161   this->setRaw(raw);
00162 }
00163 
00164 // return value as int
00165 template <int nBits>
00166 int L1GctTwosComplement<nBits>::value() const {
00167   int value, result;
00168   int maxValueInNbits;
00169   maxValueInNbits = 1<<(m_nBits-1);
00170   value  = static_cast<int>(m_data);
00171   result = value < maxValueInNbits ? value : value - (1<<MAX_NBITS) ;
00172   return result;
00173 }
00174 
00175 // add two numbers
00176 template <int nBits>
00177 L1GctTwosComplement<nBits>
00178 L1GctTwosComplement<nBits>::operator+ (const L1GctTwosComplement<nBits> &rhs) const {
00179 
00180   // temporary variable for storing the result (need to set its size)
00181   L1GctTwosComplement<nBits> temp;
00182   uint32_t sum;
00183   bool ofl;
00184 
00185   // do the addition here
00186   sum = this->raw() + rhs.raw();
00187   ofl = this->overFlow() || rhs.overFlow();
00188 
00189   //fill the temporary argument
00190   temp.setRaw(sum);
00191   temp.setOverFlow(temp.overFlow() || ofl);
00192 
00193   // return the temporary
00194   return temp;
00195 
00196 }
00197 
00198 // overload unary - (negation) operator
00199 template <int nBits>
00200 L1GctTwosComplement<nBits> L1GctTwosComplement<nBits>::operator- () const {
00201 
00202   L1GctTwosComplement<nBits> temp;
00203   temp.setValue(-this->value());
00204   temp.setOverFlow(temp.overFlow() || this->overFlow());
00205   return temp;
00206 }
00207 
00208 // overload assignment by int
00209 template <int nBits>
00210 L1GctTwosComplement<nBits>& L1GctTwosComplement<nBits>::operator= (int value) {
00211   
00212   this->setValue(value);
00213   return *this;
00214 
00215 }
00216 
00217 // Here's the check overflow function
00218 template <int nBits> 
00219 void L1GctTwosComplement<nBits>::checkOverFlow(uint32_t rawValue, uint32_t &maskValue, bool &overFlow) {
00220   uint32_t signBit = 1<<(m_nBits-1);
00221   uint32_t signExtendBits = (static_cast<uint32_t>(MAX_VALUE)-signBit)<<1;
00222   // Consider and return only MAX_NBITS least significant bits
00223   uint32_t mskRawValue = rawValue & ((1<<MAX_NBITS)-1);
00224   uint32_t value;
00225   bool ofl;
00226 
00227   if ((mskRawValue&signBit)==0) {
00228     value = mskRawValue & ~signExtendBits;
00229   } else {
00230     value = mskRawValue | signExtendBits;
00231   }
00232   ofl = value != mskRawValue;
00233 
00234   maskValue = value;
00235   overFlow  = ofl;
00236 
00237 }
00238 
00239 // overload ostream<<
00240 template <int nBits>
00241 std::ostream& operator<<(std::ostream& s, const L1GctTwosComplement<nBits>& data) {
00242 
00243   s << "L1GctTwosComplement<" << data.size() << "> raw : " << data.raw() << ", " << "value : " << data.value();
00244   if (data.overFlow()) { s << " Overflow set! "; }
00245 
00246   return s;
00247 
00248 }
00249 
00250 
00251 #endif