La majeure partie de la fonction clz()
(SW impl.) Sont optimisées pour un entier non signé 32 bits non signé .
Comment compter efficacement les zéros de premier plan dans un entier non signé 24 bits?
UPD. Caractéristiques de la cible:
CHAR_BIT 24
sizeof(int) 1
sizeof(long int) 2
sizeof(long long int) 3
Convertissez l'entier 24 bits en un 32 bits (par type punning ou explicit explicitement autour des bits), puis au 32 bits Clz et soustrayez 8.
Pourquoi le faire de cette façon? Parce que ce jour-là, vous serez difficile pressé pour trouver une machine qui traite des types de 24 bits, de manière native, en premier lieu.
Je chercherais la fonction intégrée ou intrinsèque disponible pour votre plate-forme et votre compilateur. Ces fonctions mettent généralement en œuvre le moyen le plus efficace de trouver le nombre de bits le plus significatif. Par exemple, GCC a une fonction __builtin_clz.
Si l'entier 24 bits est stocké dans une matrice d'octet (par exemple, reçu du capteur)
#define BITS(x) (CHAR_BIT * sizeof(x) - 24)
int unaligned24clz(const void * restrict val)
{
unsigned u = 0;
memcpy(&u, val, 3);
#if defined(__GNUC__)
return __builtin_clz(u) - BITS(u);
#Elif defined(__ICCARM__)
return __CLZ(u) - BITS(u);
#Elif defined(__arm__)
return __clz(u) - BITS(u);
#else
return clz(u) - BITS(u); //portable version using standard C features
#endif
}
S'il est stocké dans un entier valide
int clz24(const unsigned u)
{
#if defined(__GNUC__)
return __builtin_clz(u) - BITS(u);
#Elif defined(__ICCARM__)
return __CLZ(u) - BITS(u);
#Elif defined(__arm__)
return __clz(u) - BITS(u);
#else
return clz(u) - BITS(u); //portable version using standard C features
#endif
}
https://godbolt.org/z/z6n1rkjba
Vous pouvez ajouter plus de support de compilateurs si vous avez besoin.
N'oubliez pas si la valeur est 0
la valeur de la __builtin_clz
est indéfini pour que vous puissiez ajouter un autre chèque.