假设我有一个数据集合(例如:字符串),这些数据必须存储在一个二进制文件中,以便每个字符串都是 4 字节对齐的。
因此,如果我有一个长度为 11 的字符串,它将被填充为 12(带有空字节)。
如果我有一个长度为 24 的字符串,则不需要填充。
如果我的字符串长度为 6,它将被填充为 8 个字节。
如何计算单个表达式中所需的填充量?
我试过4 - (string_length % 4)
了,但是当我的字符串长度是 4 的倍数时它失败了。
假设我有一个数据集合(例如:字符串),这些数据必须存储在一个二进制文件中,以便每个字符串都是 4 字节对齐的。
因此,如果我有一个长度为 11 的字符串,它将被填充为 12(带有空字节)。
如果我有一个长度为 24 的字符串,则不需要填充。
如果我的字符串长度为 6,它将被填充为 8 个字节。
如何计算单个表达式中所需的填充量?
我试过4 - (string_length % 4)
了,但是当我的字符串长度是 4 的倍数时它失败了。
这看起来很奇怪,但给出了正确的答案:
(4 - (string_length % 4)) % 4
如果对齐是 2 的幂 (2,4,8,...),则有一种更快的方法来计算填充。以下运行是因为二进制 & 类似于 % 的 2 的幂:%(2^x)
并且&(2^x-1)
对正数执行相同的操作。注意: & 将删除符号位,因此总是返回正模结果。
所以(4 - (string_length & 3)) & 3
会做同样的事情(4 - (string_length % 4)) % 4
。使用正模属性,这可以简化为
(-string_length) & 3
!
如果您想将该结果添加到大小,您甚至可以进行更多优化:
padded_length = (string_length + 3) & ~3
从语义上讲,这会将数字“四舍五入”到填充大小 4。
public static final int getByteAlignedIndex(final int pVariableDataIndex, final int pVariableDataLength, final int pByteAlignment) {
return pVariableDataIndex + (pVariableDataLength & 0xFFFFFFFC) + ((((pVariableDataLength & 0b1)|((pVariableDataLength & 0b10) >> 1))) << 2);
}