2012-07-25 14 views
10

Powiedz, że mam kolekcję danych (np .: ciągi), które muszą być przechowywane w pliku binarnym wypełnionym tak, aby każdy ciąg był, powiedzmy, wyrównany do 4 bajtów.Wykładanie wymagane dla wyrównania w bajtach

Więc jeśli mam ciąg 11 znaków, zostanie on dopełniony do 12 (z pustymi bajtami).
Jeśli mam ciąg o długości 24, nie jest wymagane wypełnianie.
Jeśli mój ciąg ma długość 6, zostanie dopełniony do 8 bajtów.

Jak obliczyć ilość wypełnienia wymaganego w pojedynczym wyrażeniu?

Próbowałem 4 - (string_length % 4) ale nie kiedy mój długość łańcucha jest wielokrotnością 4.

Odpowiedz

13

To wygląda dziwnie, ale daje właściwą odpowiedź:

(4 - (string_length % 4)) % 4 
+0

Ah, zmień wynik. Nie myślałem o tym. – MxyL

11

Jest szybszy sposób obliczyć wyściółkę, jeśli wyrównanie jest potęgą dwóch (2,4,8, ...). Następujące uruchomienia, ponieważ kod binarny & jest podobny do% dla uprawnień dwóch: %(2^x) i &(2^x-1) zrobić to samo dla liczb dodatnich. Uwaga: & usunie bit znaku, dlatego zawsze zwraca pozytywny wynik modulo.

Tak więc (4 - (string_length & 3)) & 3 zrobi to samo, co (4 - (string_length % 4)) % 4. Korzystając z dodatniej właściwości modulo, można to uprościć do (-string_length) & 3!


Jeśli chcesz dodać ten wynik do wielkości można nawet zrobić więcej optymalizacje:

padded_length = (string_length + 3) & ~3 Semantycznie to 'zaokrągla w górę' numer do wielkości dopełnienia 4.

+1

Czy istnieje standardowa nazwa tej techniki? –

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