BOSS 8.0.0
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"
24#include "MdcRecoUtil/ComPackExpFloat.h"
25// #include "ErrLogger/ErrLog.hh"
26#include <iostream>
27#include <math.h>
28using std::endl;
29using std::ostream;
30
31ComPackExpFloat::ComPackExpFloat( unsigned nbits, unsigned maxexponent, double start,
32 double stop, bool center )
33 : ComPackBase<double>( start, stop, nbits ), _maxexp( maxexponent ) {
34 if ( _maxexp > 62 )
35 {
36 std::cout << "ErrMsg(fatal) "
37 << "Can't pack exponents larger than 62" << endl;
38 abort();
39 }
40 static double invln2( 1.0 / log( 2.0 ) );
41 long long one( 1 );
42 // compute how many bits used by exponent
43 _mansft = _maxexp > 0 ? (unsigned)( log( double( _maxexp ) ) * invln2 + 1.01 ) : 0;
44 _expmsk = ( 1 << _mansft ) - 1;
45 _maxman = ( 1 << ( _bitRange - _mansft ) );
46 _manmsk = _maxman - 1;
47 double invmaxman = 1.0 / _maxman;
48 long long maxnorm = ( one << ( maxexponent + 1 ) ) - 1;
49 // correct the range if we're centering the bins
50 if ( center )
51 {
52 long long norm = one << maxexponent;
53 double alpha = 1.0 / ( (double)maxnorm * _maxman * 2.0 - ( norm + 1.0 ) );
55 _maxVal += _valRange * norm * alpha;
57 // cout << "alpha = " << alpha << " norm = " << norm << endl;
58 }
59 // finish the calculations
60 _invrange = maxnorm / _valRange;
61 double invmaxnorm = _valRange / maxnorm;
62 double manoff = ( 0.5 * invmaxman + 1.0 ) * invmaxnorm;
63 double valoff = _minVal - invmaxnorm;
64 double manfac = invmaxnorm * invmaxman;
65 // pre-compute some factors and store them in an array
66 _expfac = new double[_maxexp + 1];
67 _expoff = new double[_maxexp + 1];
68 for ( unsigned iexp = 0; iexp <= _maxexp; iexp++ )
69 {
70 double expf = ( one << iexp );
71 _expoff[iexp] = valoff + manoff * expf;
72 _expfac[iexp] = manfac * expf;
73 }
74}
75
77 delete[] _expfac;
78 delete[] _expoff;
79}
80
82 d_ULong& packdata ) const {
83 static double invln2( 1.0 / log( 2.0 ) );
84 static long long one( 1 );
86 // first, figure out the exponent
87 double renorm = 1.0 + ( value - _minVal ) * _invrange;
88 if ( renorm < 1.0 )
89 {
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 {
97 long long expon = one << iexp;
98 iman = (unsigned)( _maxman * ( renorm / expon - 1.0 ) );
99 // deal with floating-point rounding, which could give a 'non-physical' result
100 if ( iman == _maxman )
101 {
102 if ( iexp == _maxexp ) iman = _maxman - 1;
103 else
104 {
105 iman = 0;
106 iexp++;
107 }
108 }
109 }
110 else
111 {
112 iexp = _maxexp;
113 iman = _maxman - 1;
114 retval = TAG_VAL_ROUND_DOWN;
115 }
116 packdata = ( iexp & _expmsk ) | ( iman & _manmsk ) << _mansft;
117 return retval;
118}
119
121 double& value ) const {
122 size_t iman = ( packdata >> _mansft ) & _manmsk;
123 size_t iexp = packdata & _expmsk;
124 value = _expoff[iexp] + iman * _expfac[iexp];
125 return TAG_OK;
126}
127
128void ComPackExpFloat::print( ostream& os ) const {
129 os << "Exponential packer for range " << _minVal << " to " << _maxVal << endl;
130 os << "Maximum exponent = " << _maxexp << endl;
131 os << "Maximum mantissa = " << _maxman << endl;
132 os << "Mantissa storage shift, mask = " << _mansft << " , " << _manmsk << endl;
133}
double alpha
const DifNumber one
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