Я читаю программу, которая содержит следующую функцию:
int f(int n) {
int c;
for (c=0;n!=0;++c)
n=n&(n-1);
return c;
}
Я не совсем понимаю, что намерена делать эта функция?
Я читаю программу, которая содержит следующую функцию:
int f(int n) {
int c;
for (c=0;n!=0;++c)
n=n&(n-1);
return c;
}
Я не совсем понимаю, что намерена делать эта функция?
Он подсчитывает число 1 в в двоичном представлении n
Предполагается показать, насколько важны комментарии.
Функция INTENDED возвращает количество бит в представлении n. В других ответах пропущено то, что функция вызывает поведение undefined для аргументов n < 0. Это связано с тем, что функция удаляет номер за один бит за раз, начиная с младшего бита и заканчивая самым высоким. Для отрицательного числа это означает, что последнее значение n до окончания цикла (для 32-битных целых чисел в 2-дополнение) равно 0x8000000. Это число INT_MIN и теперь используется в цикле в последний раз:
n = n&(n-1)
К сожалению, INT_MIN-1 является переполнением и переполнением вызывает поведение undefined. Соответствующая реализация не требуется для "округления" целых чисел, она может, например, выдать ловушку переполнения или оставить все виды странных результатов.
Это (теперь устаревшее) обходное решение из-за отсутствия инструкции POPCNT в невоенных процессорах.
Это подсчитывает количество итераций, необходимых для уменьшения n
до 0
с помощью двоичного и.
Может ли он попытаться вернуть число значимых бит в n? (Не продумал это полностью...)
Он показывает способ, как не программировать (для набора инструкций x86), используя внутреннюю/встроенную инструкцию ассемблера быстрее и лучше читать для чего-то простого подобного. (но это справедливо только для архитектуры x86, насколько я знаю, я не знаю, как это связано с ARM или SPARC или что-то еще)