PackerFloat22.hh 2.25 KB
Newer Older
dauncey's avatar
dauncey committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
#ifndef PackerFloat22_HH
#define PackerFloat22_HH

#include <iostream>
#include <cstdint>
#include <cmath>
#include <cassert>

#include "PackerBase.hh"

class PackerFloat22 : public PackerBaseUint<uint16_t> {
public:
  PackerFloat22(unsigned e, unsigned m) : fMan(m), fExp(e), fBit(fMan+(1<<fExp)-1), fDataMax((uint64_t(1)<<fBit)-1) {
    assert(m<=8*sizeof(uint16_t));
    
    std::cout << name() << "::ctor() Bits in mantissa = " << fMan
	      << ", exponent = " << fExp << ", total range = "
	      << fBit << ", data maximum = 0x" << std::hex << fDataMax
	      << std::dec << " = " << fDataMax << std::endl;
  }
 
  ~PackerFloat22() {
  }
  
  virtual std::string name() const {
    std::ostringstream sout;
    sout << "PackerFloat22E" << fExp << "M" << fMan;
    return sout.str();
  }
  
  void pack(uint32_t d) {
    uint32_t dSave(d);

    assert(d<=fDataMax);

    if(d<(uint32_t(1)<<fMan)) {
      fDatum=d;
      return;
    }

    for(unsigned i(1);i<(uint32_t(1)<<fExp);i++) {
      if(d<(uint32_t(1)<<(fMan+1))) {
	fDatum=d-(1<<fMan)+(i<<fMan);
	return;
      }
      d>>=1;
    }

    std::cout << name() << " ERROR packing value = " 
	      << printDec(dSave) << " = "
	      << printHex(dSave) << " = "
	      << printBin(dSave) << std::endl;
    assert(false);
    return;
  }

  uint32_t unpack() const {
    unsigned e(fDatum>>fMan);
    assert(e<(uint32_t(1)<<fExp));
    unsigned m(fDatum-(e<<fMan));
    assert(m<(uint32_t(1)<<fMan));

    if(e==0) return m;
    m+=(1<<fMan);
    if(e==1) return m;
    m=(m<<1)+1;
    return (m<<(e-2));
  }

  uint32_t unpackTimes2() const {
    unsigned e(fDatum>>fMan);
    assert(e<(uint32_t(1)<<fExp));
    unsigned m(fDatum-(e<<fMan));
    assert(m<(uint32_t(1)<<fMan));

    if(e==0) return 2*m;
    m+=(1<<fMan);
    if(e==1) return 2*m;

    m=(m<<16)+0x7fff;
    return (m>>(16-e));    
  }

  uint32_t dataMax() const {
    return fDataMax;
  }
  
  void print() const {
    std::cout << "PackerFloat22::print()";PackerBaseUint<uint16_t>::print();
    uint32_t up(unpack());
    std::cout << " Unpack = " 
	      << printDec(up) << " = "
	      << printHex(up) << " = "
	      << printBin(up) << std::endl;
  }

protected:
  const unsigned fMan;
  const unsigned fExp;
  const unsigned fBit;
  const uint32_t fDataMax;
};

#endif