Как написать программу для этой задачи (СИ)? - Компьютерные вопросы

Вопрос Как написать программу для этой задачи (СИ)?

Регистрация
3 Дек 2013
Сообщения
88
Репутация
0
Спасибо
0
Монет
0
Дано натуральное число меньше 16. Посчитать количество его единичных битов. Например, если дано число 9, запись которого в двоичной системе счисления равна 10012 (подстрочная цифра 2 справа от числа означает, что оно записано в двоичной системе счисления), то количество его единичных битов равно 2.

Вот, совсем не понимаю, как это должно выглядеть :(
 
Регистрация
19 Авг 2013
Сообщения
93
Репутация
0
Спасибо
0
Монет
0
Можно перебирать все биты, проверяя 0 или 1, но есть способ быстрее. Для натурального числа парой битовых операций можно выделить младший бит, отличный от нуля. Есть число, записанное в двоичном виде, n = X…X10…0, вычислим n-1 = X…X01…1 и теперь исключающее или n^(n-1) даст 0…011…1 - это битовая маска на позицию младшего бита (хотя нам нужна не она, а её дополнение). То есть как-то так. int count=0; for (; n>0; count++, n&=~(n^(n-1))); Почему мой способ быстрее, хотя он использует 3 битовые операции и одно вычитание на 1 в числе. Тогда как после преобразования c+=n%2; n/=2; в c+=n&1; n>>=1; имеем 2 битовые операции и одно сложение на 1 разряд. Считая 1 и 0 в каждом разряде равновероятным, проверим число операций на пару 10. Мой способ даёт 3+1, а перебор бит 4+2. То есть мой в среднем в полтора раза быстрее, но для худших случаев (много единичек) может считать медленнее, зато когда единиц почти нет выигрыш неимоверный!
 
Регистрация
19 Май 2013
Сообщения
91
Репутация
1
Спасибо
0
Монет
0
n = 9; // твое число < 16 (строго) c = 0; // счетчик r = 4; // кол-во разрядов (у тебя условие число меньше 16, в двоичной с/с это 4 разряда) for(int i = 0; i < r-1; i++) { //в каждом разряде смотришь что в остатке от деления и прибавляешь к счетчику c += n % 2; n /= 2; } //последний разряд можно просто добавить к счетчику c += n; //в с у тебя записан ответ
 
Регистрация
2 Фев 2013
Сообщения
85
Репутация
0
Спасибо
0
Монет
0
Задача настолько частая, что в современных процессорах есть для этого специальная команда, а в компиляторе GCC - ее вызов: unsigned int x; scanf("%d", &x); printf(__builtin_popcount(x));
 
Регистрация
20 Сен 2013
Сообщения
87
Репутация
0
Спасибо
0
Монет
0
unsigned int a=ваше число, i,b=счетчик единичных разрядов; for(i=0;i<32;i++){ if(a>2147483647){++b;} a<<=1; } Только имейте в виду что число а после этих операций будет равно 0!
 
Сверху Снизу