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
00080 int m_nBits;
00081
00082
00083 uint32_t m_data;
00084
00085
00086 bool m_overFlow;
00087
00088 static const int MAX_NBITS = 24;
00089 static const int MAX_VALUE = 1<<(MAX_NBITS-1);
00090
00091
00092
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
00100 template <int nBits>
00101 L1GctTwosComplement<nBits>::L1GctTwosComplement() {
00102 m_nBits = nBits>0 && nBits<MAX_NBITS ? nBits : 16 ;
00103 this->reset();
00104 }
00105
00106
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
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
00123
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
00133 template <int nBits>
00134 void L1GctTwosComplement<nBits>::reset() {
00135 m_data = static_cast<uint32_t>(0);
00136 m_overFlow = false;
00137 }
00138
00139
00140 template <int nBits>
00141 void L1GctTwosComplement<nBits>::setRaw(uint32_t raw) {
00142 checkOverFlow(raw, m_data, m_overFlow);
00143 }
00144
00145
00146 template <int nBits>
00147 void L1GctTwosComplement<nBits>::setValue(int value) {
00148 int chkValue, posValue;
00149 uint32_t raw;
00150
00151
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
00157 posValue = chkValue<0 ? chkValue + (1<<MAX_NBITS) : chkValue ;
00158 raw = static_cast<uint32_t>(posValue);
00159
00160
00161 this->setRaw(raw);
00162 }
00163
00164
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
00176 template <int nBits>
00177 L1GctTwosComplement<nBits>
00178 L1GctTwosComplement<nBits>::operator+ (const L1GctTwosComplement<nBits> &rhs) const {
00179
00180
00181 L1GctTwosComplement<nBits> temp;
00182 uint32_t sum;
00183 bool ofl;
00184
00185
00186 sum = this->raw() + rhs.raw();
00187 ofl = this->overFlow() || rhs.overFlow();
00188
00189
00190 temp.setRaw(sum);
00191 temp.setOverFlow(temp.overFlow() || ofl);
00192
00193
00194 return temp;
00195
00196 }
00197
00198
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
00209 template <int nBits>
00210 L1GctTwosComplement<nBits>& L1GctTwosComplement<nBits>::operator= (int value) {
00211
00212 this->setValue(value);
00213 return *this;
00214
00215 }
00216
00217
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
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
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