⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floatcompressorold.cpp

📁 对浮点型数据进行压缩
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

int FloatCompressorOld::GetMantissaBytes()
{
  return ae_mantissa_none->getNumberChars()+ae_mantissa_last->getNumberChars()+ae_mantissa_across->getNumberChars();
}

void FloatCompressorOld::FinishDecompressor(bool within)
{
  if (ad_sign_none != ad_sign_last)
  {
    ad_sign_none->done();
    ad_sign_last->done();
    ad_sign_across->done();

    ad_exponent_none->done();
    ad_exponent_last->done();
    ad_exponent_across->done();

    ad_mantissa_none->done();
    ae_mantissa_last->done();
    ae_mantissa_across->done();
  }
  dealloc_range_tables(within);
}

//-----------------------------------------------------------------------------
// SetPrecision:
//-----------------------------------------------------------------------------
void FloatCompressorOld::SetPrecision(I32 iBits)
{
  bits = iBits;
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// GetPrecision:
//-----------------------------------------------------------------------------
I32 FloatCompressorOld::GetPrecision()
{
  return bits;
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// SetMinMax:
//-----------------------------------------------------------------------------
void FloatCompressorOld::SetMinMax(F32 fMin, F32 fMax)
{
  min_float = fMin;
  max_float = fMax;
}

//-----------------------------------------------------------------------------
// UpdateMinMax:
//-----------------------------------------------------------------------------
void FloatCompressorOld::UpdateMinMax(F32 fNum)
{
  if (fNum < min_float) min_float = fNum;
  if (fNum > max_float) max_float = fNum;
}
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// GetMinMax:
//-----------------------------------------------------------------------------
void FloatCompressorOld::GetMinMax(F32& fMin, F32& fMax)
{
  fMin = min_float;
  fMax = max_float;
}
//-----------------------------------------------------------------------------

void FloatCompressorOld::compress_sign(int exponent, int sign, RangeEncoder* re_sign, RangeModel** rmSign)
{
  if (rmSign[exponent] == 0)
  {
    rmSign[exponent] = new RangeModel(2, 0, 1);
  }
  re_sign->encode(rmSign[exponent], sign);
//  fprintf(stderr,"compress_sign exp %d sign %d\n",exponent,sign);
}

int FloatCompressorOld::decompress_sign(int exponent, RangeDecoder* rd_sign, RangeModel** rmSign)
{
  if (rmSign[exponent] == 0)
  {
    rmSign[exponent] = new RangeModel(2, 0, 0);
  }
  int sign = rd_sign->decode(rmSign[exponent]);
//  fprintf(stderr,"decompress_sign exp %d sign %d\n",exponent,sign);
  return sign;
}

void FloatCompressorOld::compress_exponent(int exponentPred, int exponentReal, RangeEncoder* re_exponent, RangeModel** rmExponent)
{
  if (rmExponent[exponentPred] == 0)
  {
    rmExponent[exponentPred] = new RangeModel(256,0,1);
  }
  re_exponent->encode(rmExponent[exponentPred],exponentReal);
//  fprintf(stderr,"compress_exponent exp %d real %d\n",exponentPred,exponentReal);
}

int FloatCompressorOld::decompress_exponent(int exponentPred, RangeDecoder* rd_exponent, RangeModel** rmExponent)
{
  if (rmExponent[exponentPred] == 0)
  {
    rmExponent[exponentPred] = new RangeModel(256,0,0);
  }

  int exponentReal = rd_exponent->decode(rmExponent[exponentPred]);
//  fprintf(stderr,"decompress_exponent exp %d real %d\n",exponentPred,exponentReal);
  return exponentReal;
}

// int mist_counter = 0;
// int mist_flag = 0;

int FloatCompressorOld::compress_mantissa(int exponent, int mantissaPred, int mantissaReal, RangeEncoder* re_mantissa, RangeModel** rmMantissaHigh, RangeModel** rmMantissaLow)
{
  int c, sign;

  int bits_used = bits_for_mantissa[exponent];

  if (!bits_used) // all mantissa bits are discarded
  {
    return 0;
  }

  int bits_discarded = 23 - bits_used;

  int bits_mask = (1<<23)-(1<<bits_discarded);
  
/*
  if (mantissaReal & (1<<(bits_discarded-1)))
  {
    if ((mantissaReal + (1<<(bits_discarded-1))) < (1<<23))
    {
      mantissaReal += (1<<(bits_discarded-1));
    }
    else
    {
      mantissaReal += (1<<(bits_discarded-1));
      mist_counter++;
      mist_flag = 1;
    }
  }
*/
  mantissaReal &= bits_mask;

  c = mantissaReal - (mantissaPred&bits_mask);

  if (c < (1-(1<<22)))
  {
    c += (1<<23);
  }
  else if (c > (1<<22))
  {
    c -= (1<<23); 
  }

  // now c should lie in the interval [ - (2^22 - 1)  ...  + (2^22) ]

  if (c == (1<<22))            // the extreme misprediction
  {
    sign = -2;
    c = 0;
  }
  else
  {
    c = c >> bits_discarded;  // discard the zero bits

    if (c > 0)                // positive
    {
      sign = 0;
    }
    else if (c < 0)            // negative
    {
      sign = 1;
      c = -c;
    }
    else                      // zero
    {
      sign = -1;
    }
  }

  int bitsLowUsed = bitsLowTable[bits_used];

  if (bitsLowUsed)
  {
    int bitsHighUsed = bitsHighTable[bits_used];

    if (rmMantissaLow[exponent] == 0)
    {
      rmMantissaLow[exponent] = new RangeModel((1<<bitsLowUsed),0,1);
      if (bitsHighUsed)
      {
        rmMantissaHigh[exponent] = new RangeModel((1<<bitsHighUsed),0,1);
      }
    }

    if (bitsHighUsed)
    {
      int bitsHigh = c >> bitsLowUsed;
      re_mantissa->encode(rmMantissaHigh[exponent], bitsHigh);
      int bitsLow = c & bitsMaskTable[bits_used];
      re_mantissa->encode(rmMantissaLow[exponent], bitsLow);
    }
    else
    {
      re_mantissa->encode(rmMantissaLow[exponent], c);
    }
  }

  if (sign < 0)      // zero or extreme
  {
    if (rmZeroOrExtremeValue[exponent] == 0)
    {
      rmZeroOrExtremeValue[exponent] = new RangeModel(2,0,1);
    }
    if (sign == -1) // zero
    {
      re_mantissa->encode(rmZeroOrExtremeValue[exponent], 0);
    }
    else            // extreme
    {
      re_mantissa->encode(rmZeroOrExtremeValue[exponent], 1);
    }
  }
  else              // positive or negative
  {
    if (rmPositiveOrNegativeValue[exponent] == 0)
    {
      rmPositiveOrNegativeValue[exponent] = new RangeModel(2,0,1);
    }
    if (sign == 0)  // positive
    {
      re_mantissa->encode(rmPositiveOrNegativeValue[exponent], 0);
    }
    else            // negative
    {
      re_mantissa->encode(rmPositiveOrNegativeValue[exponent], 1);
    }
  }
  return mantissaReal;
}


int FloatCompressorOld::decompress_mantissa(int exponent, int mantissaPred, RangeDecoder* rd_mantissa, RangeModel** rmMantissaLow, RangeModel** rmMantissaHigh)
{
  int c = 0;

  int bits_used = bits_for_mantissa[exponent];

  if (!bits_used) // all mantissa bits are discarded
  {
    return 0;
  }

  int bitsLowUsed = bitsLowTable[bits_used];

  if (bitsLowUsed)
  {
    int bitsHighUsed = bitsHighTable[bits_used];

    if (rmMantissaLow[exponent] == 0)
    {
      rmMantissaLow[exponent] = new RangeModel((1<<bitsLowUsed),0,0);
      if (bitsHighUsed)
      {
        rmMantissaHigh[exponent] = new RangeModel((1<<bitsHighUsed),0,0);
      }
    }

    if (bitsHighUsed)
    {
      c = (rd_mantissa->decode(rmMantissaHigh[exponent]) << bitsLowUsed);
      c = c | rd_mantissa->decode(rmMantissaLow[exponent]);
    }
    else
    {
      c = rd_mantissa->decode(rmMantissaLow[exponent]);
    }
  }

  int bits_discarded = 23 - bits_used;

  if (c != 0) // decode sign
  {
    if (rmPositiveOrNegativeValue[exponent] == 0)
    {
      rmPositiveOrNegativeValue[exponent] = new RangeModel(2,0,0);
    }
    if (rd_mantissa->decode(rmPositiveOrNegativeValue[exponent]))
    {
      c = -(c << bits_discarded);
    }
    else
    {
      c = c << bits_discarded;
    }
  }
  else // decode zero or extreme
  {
    if (rmZeroOrExtremeValue[exponent] == 0)
    {
      rmZeroOrExtremeValue[exponent] = new RangeModel(2,0,0);
    }
    if (rd_mantissa->decode(rmZeroOrExtremeValue[exponent]))
    {
      c = (1<<(22));
    }
  }

  int bits_mask = (1<<23)-(1<<bits_discarded);

  c += (mantissaPred&bits_mask);

  // wrap back into valid range
  if (c < 0)
  {
    c += (1<<23);
  }
  else if (c >= (1<<23))
  {
    c -= (1<<23);
  }

  return c;
}

void FloatCompressorOld::reset_precision()
{
  range_exponent = -2;
  for (int i = 0; i < 256; i++)
  {
    bits_for_mantissa[i] = 23;
  }
}

void FloatCompressorOld::update_precision(float number)
{
  if (range_exponent == -2)
  {
    min_float = number;
    max_float = number;
    range_exponent = -1;
    return;
  }
  else
  {
    if (number < min_float)
    {
      min_float = number;
    }
    else if (number > max_float)
    {
      max_float = number;
    }
    else
    {
      return;
    }
  }
  float range = max_float - min_float;
  int exponent = (((U32&)range) >> 23) - ((((U32&)range) & 0x007FFFFF) == 0);
  if (exponent > range_exponent)
  {
    range_exponent = exponent;
    int i,j;
    // the mantissa of numbers with exponent max_exponent will need to
    // preserve the (bits - (range_exponent - max_exponent)) highest
    // bits
    fprintf(stderr,"exponent range %d\n",range_exponent); 
    i = 22 - bits + range_exponent;
    if (i > 255) i = 255;
    j = 22;
    while (j >= 0 && i >= 0)
    {
      if (rmMantissaNoneLow[i]) {delete rmMantissaNoneLow[i]; rmMantissaNoneLow[i] = 0;};
      if (rmMantissaNoneHigh[i]) {delete rmMantissaNoneHigh[i]; rmMantissaNoneHigh[i] = 0;};
      if (rmMantissaLastLow[i]) {delete rmMantissaLastLow[i]; rmMantissaLastLow[i] = 0;};
      if (rmMantissaLastHigh[i]) {delete rmMantissaLastHigh[i]; rmMantissaLastHigh[i] = 0;};
      if (rmMantissaAcrossLow[i]) {delete rmMantissaAcrossLow[i]; rmMantissaAcrossLow[i] = 0;};
      if (rmMantissaAcrossHigh[i]) {delete rmMantissaAcrossHigh[i]; rmMantissaAcrossHigh[i] = 0;};
      bits_for_mantissa[i] = j;
      i--;
      j--;
    }
    while (i >= 0 && (bits_for_mantissa[i] != -1))
    {
      if (rmMantissaNoneLow[i]) {delete rmMantissaNoneLow[i]; rmMantissaNoneLow[i] = 0;};
      if (rmMantissaNoneHigh[i]) {delete rmMantissaNoneHigh[i]; rmMantissaNoneHigh[i] = 0;};
      if (rmMantissaLastLow[i]) {delete rmMantissaLastLow[i]; rmMantissaLastLow[i] = 0;};
      if (rmMantissaLastHigh[i]) {delete rmMantissaLastHigh[i]; rmMantissaLastHigh[i] = 0;};
      if (rmMantissaAcrossLow[i]) {delete rmMantissaAcrossLow[i]; rmMantissaAcrossLow[i] = 0;};
      if (rmMantissaAcrossHigh[i]) {delete rmMantissaAcrossHigh[i]; rmMantissaAcrossHigh[i] = 0;};
      bits_for_mantissa[i] = -1;
      i--;
    }
  }
}

//#define USE_NEW_APPROACH

F32 FloatCompressorOld::CompressNone(F32 fReal)
{
  num_predictions_none++;

  I32 signReal = (((U32&)fReal) & 0x80000000) == 0x80000000;
  I32 exponentReal = (((U32&)fReal) & 0x7F800000) >> 23;
  I32 mantissaReal = (((U32&)fReal) & 0x007FFFFF);

  if (bits_for_mantissa[exponentReal] >= 0)
  {
    compress_exponent(0,exponentReal,ae_exponent_none,rmExponentNone);
    compress_sign(0,signReal,ae_sign_none,rmSignNone);
    mantissaReal = compress_mantissa(exponentReal,0,mantissaReal,ae_mantissa_none,rmMantissaNoneLow,rmMantissaNoneHigh);
    ((U32&)fReal) = (((U32&)fReal) & 0xFF800000) | mantissaReal;

/*
    if (mist_flag)
    {
      exponentReal++;
      if (mantissaReal)
      {
        mantissaReal = (mantissaReal+1)/2;
      }
    }
    if (signReal)
    {
      ((U32&)fReal) = 0x80000000 | (exponentReal << 23) | mantissaReal;
    }
    else
    {
      ((U32&)fReal) = (exponentReal << 23) | mantissaReal;
    }
*/

    if (exponentReal == 255)
    {
      fprintf(stderr,"WARNING: exponentReal is 255 -> infinite number\n");
    }
    else
    {
      if (bits) update_precision(fReal);
    }

    return fReal;
  }
  else // the float is quantized to 0.0f
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -