获取byte[]
的字节表示(即int
),但只使用3个字节(而不是4个字节),这是一种很好的,可读的方法吗?我正在使用Hadoop / Hbase,他们的Bytes
实用程序类具有toBytes
函数,但总是使用4个字节。
理想情况下,我还想要一种好的,可读的编码方式,尽可能少的字节,即如果数字适合一个字节,那么只使用一个。
请注意我将其存储在byte[]
中,因此我知道数组的长度,因此不需要可变长度编码。这是关于找到一种优雅的方式进行演员表。
答案 0 :(得分:4)
对此的一般解决方案是不可能的。
如果可能,您可以迭代地应用该函数以获得无限制的数据压缩。
您的域可能会对允许将它们压缩为24位的整数有一些限制。如果存在此类限制,请在问题中解释。
常见的可变大小编码是将每个字节的7位用于数据,将高位用作标志,以指示当前字节何时是最后一个。
您可以预测int
上使用a utility method对Integer
进行编码所需的字节数:
int n = 4 - Integer.numberOfLeadingZeros(x) / 8;
byte[] enc = new byte[n];
while (n-- > 0)
enc[n] = (byte) ((x >>> (n * 8)) & 0xFF);
请注意,这会将0编码为空数组,将其他值编码为 little-endian 格式。通过一些操作可以轻松修改这些方面。
答案 1 :(得分:1)
如果需要表示整个2 ^ 32个现有的4字节整数,则需要选择:
看看UTF-8如何编码Unicode字符,您可能会获得一些见解。 (你使用一些简短的前缀来描述必须为该unicode字符读取多少字节,然后你读取那么多字节并解释它们。)
答案 2 :(得分:1)
尝试使用ByteBuffer。如果需要,您甚至可以设置小端模式:
int exampleInt = 0x11FFFFFF;
ByteBuffer buf = ByteBuffer.allocate(Integer.SIZE / Byte.SIZE);
final byte[] threeByteBuffer = new byte[3];
buf.putInt(exampleInt);
buf.position(1);
buf.get(threeByteBuffer);
或签名最短的Big Endian:
BigInteger bi = BigInteger.valueOf(exampleInt);
final byte[] shortestSigned = bi.toByteArray();
答案 3 :(得分:0)
将int
转换为4 byte
s数组,并迭代它,如果每个高位字节为零,则将其从数组中删除。
类似的东西:
byte[] bytes = toBytes(myInt);
int neededBytes = 4;
for (;neededBytes > 1; i--) {
if (bytes[neededBytes - 1] != 0) {
break;
}
}
byte[] result = new byte[neededBytes];
// then just use array copy to copy first neededBytes to result.
答案 4 :(得分:0)
你可以从这样的事情开始:
byte[] Convert(int i)
{ // warning: untested
if (i == 0)
return new byte[0];
if (i > 0 && i < 256)
return new byte[]{(byte)i};
if (i > 0 && i < 256 * 256)
return new byte[]{(byte)i, (byte)(i >> 8)};
if (i > 0 && i < 256 * 256 * 256)
return new byte[]{(byte)i, (byte)(i >> 8), (byte)(i >> 16)};
return new byte[]{(byte)i, (byte)(i >> 8), (byte)(i >> 16), (byte)(i >> 24)};
}
你需要决定你是想成为小端还是大端。请注意,负数以4个字节编码。
答案 5 :(得分:0)
如果我理解你真的那么,拼命想要节省空间,即使以牺牲神秘的位洗牌为代价:任何阵列类型都是不必要的奢侈品,因为你不能使用少于一个整数字节的长度=寻址空间256知道最多需要4个。所以我会为长度和符号标志保留4位,并将其余部分与该字节数对齐。如果你的MSB小于128,你甚至可以再保存一个字节。我认为符号标志对于能够以小于4个字节表示负数的能力很有用。最好每次都有位(即使是正数),而不是4字节的开销来表示-1。
无论如何,在您对数据集进行一些统计,实际可压缩的整数数量以及压缩开销是否值得付出努力之前,这一切都很薄。