Katakanlah Anda memiliki nomor:0x1006
Untuk beberapa alasan Anda ingin menyelaraskannya ke 4
batas byte.
Dengan batas 4 byte, Anda tahu bahwa nilai yang disejajarkan adalah 0x1000
, 0x1004
, 0x1008
, dll. Kemudian Anda juga mengetahui nilai rata dari 0x1006
adalah 0x1008
.
Bagaimana Anda mendapatkan 0x1008
? Masker perataan untuk nilai perataan 4
adalah (4 - 1) = 0x03
Sekarang 0x1006 + 0x03 = 0x1009
dan 0x1009 & ~0x03 = 0x1008
Operasi ini adalah __ALIGN_MASK
makro.
Jika Anda ingin memberikan nilai 4
(perataan) bukan langsung 0x03
(topeng pelurusan), Anda memiliki ALIGN
makro
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
perataan, a
, dilemparkan ke x
jenis, dan kemudian satu dikurangi. Penyelarasan harus pangkat 2, sehingga menghasilkan sejumlah bit-pattern 00..011..11
dari x
jenisnya, topeng (k
1s jika a = 2^k
).
Lalu
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
menambahkan nilai topeng ke x
, sehingga (x)+ (mask)
setidaknya sebesar kelipatan terkecil dari perataan yang tidak lebih kecil dari x
dan lebih kecil dari kelipatan berikutnya yang lebih besar. Kemudian bitwise dan dengan pelengkap topeng mengurangi angka itu menjadi kelipatan perataan itu.
Untuk topeng dalam bentuk 2^k - 1
, perhitungan
(x + mask) & ~mask
sama dengan
(x + 2^k - 1) - ((x + 2^k - 1) % (2^k))
atau
((x + 2^k - 1)/(2^k)) * (2^k)