LINUX.ORG.RU

помогите разобраться с макросом


0

1
#define ALIGNTO 4
#define ALIGN(len) ( ((len)+ALIGNTO-1) & ~(ALIGNTO-1) )

Как я понимаю, результатом ALIGN является число кратное ALIGNTO. Непонятна только математика процесса, никак не могу въехать. Если с первой частью выражения более-менее ясно, то вот со второй не очень (вроде бы служит для отбрасывания младших битиков, но зачем?)

Буду признателен за снятие с ручника :)

PS. вообще данный метод является ли типичным при выравниваниях по нужной границе?

★★

Последнее исправление: cruz7 (всего исправлений: 1)

Двоичное число [01]*0 делится на 2.
Двоичное число [01]*00 делится на 4.
Двоичное число [01]*000 делится на 8.
И т. д.

anonymous
()

> вроде бы служит для отбрасывания младших битиков, но зачем?

Как раз чтобы округлить число. Эквивалентная в данном случае запись: (...) / ALIGNTO * ALIGNTO.

Метод традиционный и юзается где ни попадя. Для выделения блока памяти с наперед заданным выравниванием можно юзать функцию posix_memalign.

const86 ★★★★★
()

Макрос работает только для степеней двойки, отсюда и логика его работы

unC0Rr ★★★★★
()

представим число len в двоичном виде, например
10101010
len кратна 4 только если младшие два бита нулевые.
Прибавляя к len (4-1)
00000011
мы получим вытеснение единицы из младших двух разрядов (только если len не была кратна 4):
10101101
(вытеснение единицы в старший разряд этвивалентно прибавлению 4)
далее отбрасываем младшие два бита, чтобы получить результат кратным 4
10101100

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.