/* returns greatest power of 2 less than or equal to x, branch-free */
/* Source: Hacker's Delight, First Edition. */
int
flp2(int x)
{
x = x | (x>>1);
x = x | (x>>2);
x = x | (x>>4);
x = x | (x>>8);
x = x | (x>>16);
return x - (x>>1);
}
To zabawne, aby go zbadać i zobaczyć, jak działa. Myślę, że jedyny sposób, abyś wiedział na pewno, które z rozwiązań, które widzisz, będą optymalne dla twojej sytuacji, to wykorzystać je wszystkie w opcjach tekstowych i profilować je i zobaczyć, które jest najbardziej efektywne dla twojego celu.
Będąc bez gałęzi, ten prawdopodobnie będzie dość dobry pod względem wydajności w stosunku do niektórych innych, ale powinieneś przetestować go bezpośrednio, aby mieć pewność.
Jeśli chcesz najmniejszą moc dwóch większą lub równą X, można użyć nieco inne rozwiązanie:
unsigned
clp2(unsigned x)
{
x = x -1;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
return x + 1;
}
Jeśli używasz GCC, możesz użyć '1 << CHAR_BIT * sizeof x - __builtin_clz (x)', pod warunkiem, że 'x' ma typ' unsigned int' lub, w normalnych systemach, 'int'. Istnieje również "__builtin_clzl" dla 'unsigned long'. Niektóre kompilatory bez GCC również obsługują to rozszerzenie. To będzie szybsze niż jakakolwiek inna dotychczasowa odpowiedź na procesory, które mają instrukcję "znajdź pierwszy bit set". –
edytowanie notatek z "> wartości całkowitej" na "> = wartość całkowita" – bph
Teraz wszyscy muszą ponownie zmienić swoje odpowiedzi. :-) –