Премини към съдържанието
RandomGuy

Проверка колко бита е едно число

Препоръчан отговор


Здравейте,

Искам да проверя колко 0 и 1 има в едно число.


#include <iostream>

using namespace std;

void func(int num)
{
    int zeroCnt = 0, oneCnt = 0;
    
    for(int i = 0;i < 32;i++)
    {
        if((num >> i) & 1)
        {
            oneCnt++;   
        }
        else
        {
            zeroCnt++;   
        }
    }
    cout << oneCnt << " " << zeroCnt << endl;
}
int main()
{
  func(22);
}
Въртя for-a до 32, защото нали инт е 32 бита, но брои 29 нули и 3 единици което е нормално. Как мога да разбера броя на битовете на числото и да проверявам до тях. Благодаря предварително за отговорите. 

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
преди 20 минути, RandomGuy написа:

...

Като най-просто - ползвай очевидното решение - вместо да броиш нулите отбелязваш, къде е последната засечена единица. Иначе има по-ефективни начини да намираш битовете на числото, ама ти така и така искаш и да ги броиш...

Примерно последната единица ти е на i=5, и единиците са ти 3 - значи 6 бита число - 3 единици и 3 нули.

Редактирано от flare (преглед на промените)

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Благодаря flare за отговора. Хитро решение не се бях сетил :)

преди 3 минути, Реджеп Иведик написа:

y = (int)log2((double)x);

 

Мерси :)

Редактирано от RandomGuy (преглед на промените)

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
преди 1 минута, Реджеп Иведик написа:

y = (int)log2((double)x);

 

И ако x-a e отрицателен - отиваме в черешките.


Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Всъщност и за положителни дава с 1 по-малък резултат, а отрицателните заради знаковия бит ще ги дава все 32 бита

(int)log2((double)(unsigned)x)+1

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
преди 25 минути, ined написа:

Всъщност и за положителни дава с 1 по-малък резултат, а отрицателните заради знаковия бит ще ги дава все 32 бита

(int)log2((double)(unsigned)x)+1

Ми не. за отрицателни връща nan или ексепшън, в зависимост от имплементацията, което е очаквано поведение имайки предвид къде е дефиниран логаритъмът.

Отделно, в зависимост от компилатора, може да няма log2 и да си го смяташ на ръчица. Бе с две думи яко овъркил за нищо.

Редактирано от flare (преглед на промените)

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
y = (x < 0) ? -1 : (x == 0) ? 0 : (int)log2((double)x) + 1;

Ей добре не сте счетоводители. Ще оставите хората гладни. Ама господ си знае работата

Редактирано от Реджеп Иведик (преглед на промените)

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Най лесно става с интринсики или на асемблер

Ама не е портабъл.

Вижуъл студио

#include "stdafx.h"
#include <intrin.h>


int _tmain(int argc, _TCHAR* argv[])
{
	unsigned long long x = 18;
	unsigned long y;
	if (x == 0)
	{
		printf("%d", -1);
		return 0;
	}
	_BitScanReverse(&y, x);
	
	printf("%u", y + 1);
	return 0;
}

 

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
преди 10 минути, Реджеп Иведик написа:

Най лесно.

 

Най-лесно е това дето наистина е най-лесно. Ако е малко повторения бих го направил точно с най-обикновен цикъл. Ако са адски много повторения - 8битова lookup table и побайтово. Разликата в скоростта ще е незначителна спрямо повечето други портваеми решения и може едновременно да брои и вдигнатите битове. Оттам нататък, ще му мисля, чак ако точно това е най-важния проблем във вселената. Ужасно вярно е че в преждевременната оптимизация се корени цялото зло.

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
преди 14 минути, flare написа:

8битова lookup table и побайтово.

8 битова лукъп тейбъл одобрявам, но може вместо побайтово да се проверява с по 16 бита на веднъж. Отгоре надолу. Ако случиш 16 битова нула печелиш една проверка по малко. Ако не е нула, ще знаеш точно в кой байт е най високия бит и с него ще лукапнеш таблицата

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Добавете отговор

Можете да публикувате отговор сега и да се регистрирате по-късно. Ако имате регистрация, влезте в профила си за да публикувате от него.

Гост
Напишете отговор в тази тема...

×   Вмъкнахте текст, който съдържа форматиране.   Премахни форматирането на текста

  Разрешени са само 75 емотикони.

×   Съдържанието от линка беше вградено автоматично.   Премахни съдържанието и покажи само линк

×   Съдържанието, което сте написали преди беше възстановено..   Изтрий всичко

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Добави ново...

Информация

Поставихме бисквитки на устройството ви за най-добро потребителско изживяване. Можете да промените настройките си за бисквитки, или в противен случай приемаме, че сте съгласни с нашите Условия за ползване