15

Say I have a collection of data (eg: strings) that must be stored in a binary file padded so that each string is, say, 4-byte aligned.

So if I have a string of length 11, it would get padded to 12 (with null bytes).
If I have a string of length 24, then no padding is necessary.
If my string has a length of 6, it would get padded to 8 bytes.

How do I compute the amount of padding required in a single expression?

I tried 4 - (string_length % 4) but it fails when my string length is a multiple of 4.

MxLDevs
  • 19,048
  • 36
  • 123
  • 194

3 Answers3

23

This looks odd but gives the right answer:

(4 - (string_length % 4)) % 4
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
18

There is a faster way to compute the padding, if the alignment is a power of two (2,4,8,...). The following runs because binary & is similar to % for powers of two: %(2^x) and &(2^x-1) do the same for positive numbers. Attention: & will delete the sign bit and therefore always returns the positive modulo result.

So (4 - (string_length & 3)) & 3 will do the same as (4 - (string_length % 4)) % 4. Using the positive modulo property this can be simplified to (-string_length) & 3!


If you wanna add that result to the size you can even do more optimizations:

padded_length = (string_length + 3) & ~3 Semantically this 'rounds up' the number to the padding size of 4.

Johannes Jendersie
  • 980
  • 10
  • 16
-2
public static final int getByteAlignedIndex(final int pVariableDataIndex, final int pVariableDataLength, final int pByteAlignment) {
    return pVariableDataIndex + (pVariableDataLength & 0xFFFFFFFC) + ((((pVariableDataLength & 0b1)|((pVariableDataLength & 0b10) >> 1))) << 2);
}
Mapsy
  • 4,192
  • 1
  • 37
  • 43