BOSS 6.6.4.p03
BESIII Offline Software System
Loading...
Searching...
No Matches
ComPackExpFloat.cxx
Go to the documentation of this file.
1//--------------------------------------------------------------------------
2// File and Version Information:
3// $Id: ComPackExpFloat.cxx,v 1.2 2009/12/23 02:59:56 zhangy Exp $
4//
5// Description:
6// class ComPackExpFloat
7//
8// Environment:
9// Software developed for the BaBar Detector at the SLAC B-Factory.
10//
11// Author List:
12// Dave Brown 10/12/00
13//
14// Copyright Information:
15// Copyright (C) 2000 LBNL
16//
17// History:
18// Migration for BESIII MDC
19//
20//
21//--------------------------------------------------------------------------
22
23//#include "BaBar/BaBar.hh"
25//#include "ErrLogger/ErrLog.hh"
26#include <math.h>
27#include <iostream>
28using std::endl;
29using std::ostream;
30
32 unsigned maxexponent,
33 double start,
34 double stop,
35 bool center ) :
36 ComPackBase<double>(start,stop,nbits),
37 _maxexp(maxexponent) {
38 if(_maxexp > 62 ) {
39 std::cout<<"ErrMsg(fatal) "<< "Can't pack exponents larger than 62" << endl;
40 abort();
41 }
42 static double invln2(1.0/log(2.0));
43 long long one(1);
44// compute how many bits used by exponent
45 _mansft = _maxexp>0?(unsigned)(log(double(_maxexp))*invln2+1.01):0;
46 _expmsk = (1<<_mansft)-1;
47 _maxman = (1<<(_bitRange-_mansft));
48 _manmsk = _maxman-1;
49 double invmaxman = 1.0/_maxman;
50 long long maxnorm = (one<<(maxexponent+1))-1;
51// correct the range if we're centering the bins
52 if(center) {
53 long long norm = one<<maxexponent;
54 double alpha = 1.0/((double)maxnorm*_maxman*2.0 - (norm + 1.0));
56 _maxVal += _valRange*norm*alpha;
58// cout << "alpha = " << alpha << " norm = " << norm << endl;
59 }
60// finish the calculations
61 _invrange = maxnorm/_valRange;
62 double invmaxnorm = _valRange/maxnorm;
63 double manoff = (0.5 * invmaxman+1.0) * invmaxnorm;
64 double valoff = _minVal - invmaxnorm;
65 double manfac = invmaxnorm * invmaxman;
66// pre-compute some factors and store them in an array
67 _expfac = new double[_maxexp+1];
68 _expoff = new double[_maxexp+1];
69 for(unsigned iexp=0;iexp<=_maxexp;iexp++){
70 double expf = (one<<iexp);
71 _expoff[iexp] = valoff + manoff*expf;
72 _expfac[iexp] = manfac*expf;
73 }
74}
75
77{
78 delete [] _expfac;
79 delete [] _expoff;
80}
81
83ComPackExpFloat::pack (const double value, d_ULong & packdata) const {
84 static double invln2(1.0/log(2.0));
85 static long long one(1);
87// first, figure out the exponent
88 double renorm = 1.0+(value-_minVal)*_invrange;
89 if(renorm<1.0){
90 renorm=1.0;
91 retval = TAG_VAL_ROUND_UP;
92 }
93 unsigned iexp = unsigned(log(renorm)*invln2);
94 unsigned iman(0);
95 if(iexp<=_maxexp){
96 long long expon = one<<iexp;
97 iman = (unsigned)( _maxman*(renorm/expon - 1.0) );
98// deal with floating-point rounding, which could give a 'non-physical' result
99 if(iman==_maxman){
100 if(iexp==_maxexp)
101 iman=_maxman-1;
102 else {
103 iman=0;
104 iexp++;
105 }
106 }
107 } else {
108 iexp=_maxexp;
109 iman = _maxman-1;
110 retval = TAG_VAL_ROUND_DOWN;
111 }
112 packdata = (iexp&_expmsk) | (iman&_manmsk)<<_mansft;
113 return retval;
114}
115
117ComPackExpFloat::unpack (const d_ULong packdata, double & value) const {
118 size_t iman = (packdata>>_mansft)&_manmsk;
119 size_t iexp = packdata&_expmsk;
120 value = _expoff[iexp] + iman * _expfac[iexp];
121 return TAG_OK;
122}
123
124void
125ComPackExpFloat::print(ostream& os) const {
126 os << "Exponential packer for range " << _minVal << " to " << _maxVal << endl;
127 os << "Maximum exponent = " << _maxexp << endl;
128 os << "Maximum mantissa = " << _maxman << endl;
129 os << "Mantissa storage shift, mask = " << _mansft << " , " << _manmsk << endl;
130}
131
unsigned int d_ULong
Definition: BesODMGTypes.h:96
const DifNumber one
const double alpha
virtual ~ComPackExpFloat()
ComPackExpFloat(unsigned nbits, unsigned maxexponent, double start, double stop, bool center=false)
virtual StatusCode unpack(const d_ULong, double &) const
virtual StatusCode pack(const double, d_ULong &) const
void print(std::ostream &os) const