📄 floatcompressorold.cpp
字号:
}
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 + -