我正在阅读avro格式规范并尝试了解其实现。以下是解码long value的方法:
@Override
public long readLong() throws IOException {
ensureBounds(10);
int b = buf[pos++] & 0xff;
int n = b & 0x7f;
long l;
if (b > 0x7f) {
b = buf[pos++] & 0xff;
n ^= (b & 0x7f) << 7;
if (b > 0x7f) {
b = buf[pos++] & 0xff;
n ^= (b & 0x7f) << 14;
if (b > 0x7f) {
b = buf[pos++] & 0xff;
n ^= (b & 0x7f) << 21;
if (b > 0x7f) {
// only the low 28 bits can be set, so this won't carry
// the sign bit to the long
l = innerLongDecode((long)n);
} else {
l = n;
}
} else {
l = n;
}
} else {
l = n;
}
} else {
l = n;
}
if (pos > limit) {
throw new EOFException();
}
return (l >>> 1) ^ -(l & 1); // back to two's-complement
}
问题是为什么我们总是检查0x7f
是否少于我们刚读过的字节?
答案 0 :(得分:5)
这是一种比特打包形式,其中每个byte
的最高有效位用于确定是否应该读取另一个byte
。从本质上讲,这允许您以比通常需要的更少的字节数对值进行编码。但是,有一点需要注意,如果数字很大,那么将需要超过正常字节数。因此,使用较小的值时,这是成功的。
回答你的问题,0x7F
是0111_1111
的二进制文件。您可以看到最高有效位用作标志位。
答案 1 :(得分:2)
0b1111111
(127),无符号btye的最大数量,为一个标志保存一个。