web-dev-qa-db-fra.com

Comment compter efficacement les zéros de premier plan dans un entier non signé 24 bits?

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
2
pmor

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.

1
datenwolf

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.

0
0___________