Вычисление, требуемое для выравнивания по n-байту

Скажем, у меня есть набор данных (например: строки), которые должны быть сохранены в двоичном файле, дополненном так, чтобы каждая строка была, скажем, выровнена на 4 байта.

Итак, если у меня есть строка длиной 11, она будет заполнена до 12 (с нулевыми байтами).
Если у меня есть строка длиной 24, то никакое дополнение не требуется.
Если моя строка имеет длину 6, она будет дополняться 8 байтами.

Как вычислить количество отступов, требуемое в одном выражении?

Я пробовал 4 - (string_length % 4), но он терпит неудачу, когда моя длина строки кратна 4.

Ответ 1

Это выглядит странно, но дает правильный ответ:

(4 - (string_length % 4)) % 4

Ответ 2

Существует более быстрый способ вычисления отступов, если выравнивание равно двум (2,4,8,...). Следующие пробеги, потому что двоичные и аналогичны% для степеней двух: %(2^x) и &(2^x-1) делают то же самое для положительных чисел. Внимание: и будет удалять бит знака и поэтому всегда возвращает положительный результат по модулю.

Итак, (4 - (string_length & 3)) & 3 будет делать то же самое, что и (4 - (string_length % 4)) % 4. Используя положительное свойство modulo, это можно упростить до (-string_length) & 3!


Если вы хотите добавить этот результат к размеру, вы можете даже сделать больше оптимизаций:

padded_length = (string_length + 3) & ~3 Семантически это "округляет" число до размера прокладки 4.

Ответ 3

public static final int getByteAlignedIndex(final int pVariableDataIndex, final int pVariableDataLength, final int pByteAlignment) {
    return pVariableDataIndex + (pVariableDataLength & 0xFFFFFFFC) + ((((pVariableDataLength & 0b1)|((pVariableDataLength & 0b10) >> 1))) << 2);
}