template <int bits, typename SymbolCoder> void writer(SymbolCoder& coder, int min, int max, int value) { assert(min<=max); assert(value>=min); assert(value<=max); // avoid doing anything if the value is already known if (min == max) return; if (value == 0) { // value is zero coder.write(true, BIT_ZERO); return; } // only output zero bit if value could also have been zero if (max >= 0 && min <= 0) coder.write(false,BIT_ZERO); int sign = (value > 0 ? 1 : 0); if (max > 0 && min < 0) { // only output sign bit if value can be both pos and neg if (min < 0 && max > 0) coder.write(sign,BIT_SIGN); } if (sign && min <= 0) min = 1; if (!sign && max >= 0) max = -1; const int a = abs(value); const int e = maniac::util::ilog2(a); int amin = sign ? abs(min) : abs(max); int amax = sign ? abs(max) : abs(min); int emax = maniac::util::ilog2(amax); int i = maniac::util::ilog2(amin); while (i < emax) { // if exponent >i is impossible, we are done if ((1 << (i+1)) > amax) break; // if exponent i is possible, output the exponent bit coder.write(i==e, BIT_EXP, i); if (i==e) break; i++; } // e_printf("exp=%i\n",e); int have = (1 << e); int left = have-1; for (int pos = e; pos>0;) { int bit = 1; left ^= (1 << (--pos)); int minabs1 = have | (1<<pos); // int maxabs1 = have | left | (1<<pos); // int minabs0 = have; int maxabs0 = have | left; if (minabs1 > amax) { // 1-bit is impossible bit = 0; } else if (maxabs0 >= amin) { // 0-bit and 1-bit are both possible bit = (a >> pos) & 1; coder.write(bit, BIT_MANT, pos); } have |= (bit << pos); }
template <typename SymbolCoder> void writer(SymbolCoder& coder, int bits, int value) { int pos=0; while (pos++ < bits) { coder.write(value&1, BIT_MANT, pos); value >>= 1; } }