結合lucene談談浮點數的壓縮問題

先說說單精度float類型的壓縮方法,lucene裏面是將-1.0~125.0之間浮點數而且小數點部分爲0的值使用1個字節壓縮,固然必須排除-0.0f,其他的正數使用4個字節存儲,負數使用5個字節存儲(第一個字節是0xff)其他是原始的4個字節。源碼

根據第一個字節就能對壓縮的數值進行解析,-1~125的二進制形式爲0b11111111~0b01111101,lucene將值加1而且將最高位置1,這樣值就變成了0b10000000~0b11111110,考慮其他正數的最高位是符號位而且以0打頭0b0XXXXXXX,其他負數的最高位是0b11111111,能夠看出這三種狀況是徹底不衝突的,相信你們也能看出來爲何-1.0~125.0要排除-0.0f了吧,由於-0.0f的首字節是0b10000000跟前面(0b10000000~0b11111110)是衝突的。有興趣的能夠看看lucene的源碼:it

 

int intVal = (int) f;
    final int floatBits = Float.floatToIntBits(f);
原理

    if (f == intVal
        && intVal >= -1
        && intVal <= 0x7D
        && floatBits != NEGATIVE_ZERO_FLOAT) {
      // small integer value [-1..125]: single byte
      out.writeByte((byte) (0x80 | (1 + intVal)));
    } else if ((floatBits >>> 31) == 0) {
      // other positive floats: 4 bytes
      out.writeInt(floatBits);
    } else {
      // other negative float: 5 bytes
      out.writeByte((byte) 0xFF);
      out.writeInt(floatBits);
    }
二進制

實際上雙精度double類型的原理也是相似的,實現的時候跟float的方式稍有不一樣float

相關文章
相關標籤/搜索