/* 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);
}
È divertente studiarlo e vedere come funziona. Penso che l'unico modo per farti sapere con certezza quale delle soluzioni che vedrai sarà ottimale per la tua situazione è di usarli tutti in un dispositivo di testo e di tracciarlo e vedere quale è il più efficiente per il tuo scopo.
Essendo privo di ramificazioni, è probabile che questo rappresenti prestazioni relativamente buone rispetto ad altri, ma è necessario verificarlo direttamente per essere sicuri.
Se si desidera che il minimo potenza di due superiore o uguale a X, è possibile utilizzare una soluzione leggermente diversa:
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;
}
fonte
2013-03-20 14:04:06
Se si utilizza GCC, è possibile utilizzare '1 << CHAR_BIT * sizeof x - __builtin_clz (x)', a condizione che 'x' abbia tipo' unsigned int' o, nei sistemi normali, 'int'. C'è anche '__builtin_clzl' per' unsigned long'. Alcuni compilatori non GCC supportano anche questa estensione. Questo sarà più veloce di qualsiasi altra risposta finora sui processori che hanno un'istruzione "trova il primo bit impostato". –
nota modifica da '> un valore intero' a '> = un valore intero' – bph
Ora tutti devono cambiare le loro risposte di nuovo. :-) –