Blog programisty o C/C++ i PHP

Programowanie w C/C++ i PHP. Blog pełen wskazówek, porad, analiz i opisów.

Jak znaleźć wartość najstarszego ustawionego bitu liczby 32-bitowej? (cz. 1)

październik 1st, 2006 in Programowanie w C/C++

Jeśli nie jesteś ambitny to nie czytaj dalej tego artykułu. Jest on bowiem przeznaczony dla naprawdę zatwardziałych programistów, którzy wiedzą juz coś nie coś o assemblerze.

Oto przykładowe rozwiązanie:

unsigned long int getBitVectorEigenVal(unsigned long int wartosc)
{
	asm
	{
	mov EDX, wartosc;
	xor ECX, ECX;
	bsr EAX, EDX;
	jz not_found
	bts ECX, EAX;
	not_found:
	mov EAX, ECX;
	}
}

Skorzystamy z języka assembler, gdyż począwszy od procesorów x386 jądro obsługuje bardzo nam przydatne rozkazy przetwarzania bitowego oraz instrukcje 32-bitowe. Rozkaz bsr znajduje 1-wszy (w kolejności od najstarszego) bit, którego wartością jest “1″. Jeśli taki zapalony bit istnieje jego numer (powiększony o 1) zostaje wpisany do rejestru EAX. Jeśli wszystkie bity argumentu były wyzerowane to ustawiana jest flaga Z (w takim przypadku rejestr EAX nie jest zmieniany). Następną czynnością jest zamiana uzyskanego numeru bitu na odpowiadającą mu wartość (czyli jeśli wyjdzie nam bit nr 3, to jego wartość jest 8 - licząc od 1 bo tak działają te instrukcje). Korzystamy z instrukcji bts, która to zapala bit o podanym numerze w rejestrze ECX, który został wcześniej wyzerowany za pomocą instrukcji xor ECX, ECX. Teraz już pozostaje zwrócić wynik, dlatego kopiujemy zawartść rejestru ECX do EAX, bowiem funkcje zwracają wynik właśnie poprzez ten rejestr lub AX lub AL zależnie od rozmiaru wyniku (nasz jest 32-bitowy).
No i nadeszła najważniejsza chwila. Chwila testów.

	unsigned long int ulValue = 4336801;
	unsigned long int ulMask = 4194304
	unsigned long int ulEigValue = getBitVectorEigenVal(ulValue);

	if (ulMask & ulValue)
	{
	// To wykona się wtedy i tylko w tedy gdy bit charakterystyczny przekazanej jako argument liczby
	// znajduje się także w masce
	}

Zapraszam Cię na część drugą. Rozszerzymy działanie funkcji na naprawdę baaaaardzo ;-D długie łancuchy bitów.

Tags: ,

Leave a Reply