2009-07-20 7 views
0

Je suis à la recherche d'un moyen rapide pour configurer une méthode de retour d'un masque basé sur un nombre. Fondamentalement, 4 bits doivent être émis avant l'entrée numéro. Voici une bonne idée de ce que je veux dire:Rapide Bitwise Question en C++

foo (1); // renvoie 0x000F foo (2); // renvoie 0x00FF foo (3); // renvoie 0x0FFF foo (4); // renvoie 0xFFFF

Je pourrais juste utiliser une grosse instruction switch, mais je ne sais pas quelle est la largeur du type d'entrée à l'avance. (Ceci est une fonction de modèle)

Voici était la première chose que j'ai essayé:

template <typename T> T foo(unsigned short length) 
{ 
    T result = 0xF; 
    for (unsigned short idx = length; idx > 0; idx--) 
    { 
     result = (result << 4 | 0xF); 
    } 
    return result; 
} 

mais il passe beaucoup de temps à faire maintenence sur la boucle. Y a-t-il des façons intelligentes de faire cela auxquelles je n'ai pas pensé?

Billy3

Répondre

9

Que diriez-vous quelque chose comme:

template <typename T> T foo(unsigned short length) 
{ 
    return (T(1) << (length * 4)) - 1; 
} 
+0

Après avoir passé environ 10 minutes à comprendre pourquoi ça marche, ça donne un coup de pied à A **! Merci! –

+0

@Charles Bailey, eh bien, il m'a fallu plus de 10 minutes puisque ma programmation de modèles est assez rouillée et je dois convenir que c'est une solution très agréable et élégante. La clé est de réaliser que T (1) sera transformé en une valeur de 1 pour le type puis l'un est décalé de sorte qu'il sera dans le prochain quartet puis soustrait 1 pour obtenir l'0xf. Donc, un exemple pour short non signé serait 0x0001 alors décalé serait 0x0010 alors soustraire un pour arriver à 0x000f. –

6

Il suffit de créer un tableau qui associe chaque numéro au bitmask approprié.

par exemple. map [1] = 0x00F etc.

Ce sera le plus rapide.

+0

Battez-moi en une seconde. – GManNickG

+0

A la place, si vous utilisez un vecteur, ne sera-t-il pas plus rapide que vous pouvez utiliser v [1], v [2], etc., ce qui sera une opération à temps constant? – Naveen

+0

Désolé - Je ne connais pas la taille du tableau car je ne connais pas le sizeof() du type lorsque la fonction est appelée. –

2

Si c'est juste littéraux, vous pouvez même le faire à la compilation en utilisant une fonction méta. Détournement de l'idée de Charles:

template <typename T, unsigned short L> 
struct Foo { 
    enum { result = (T(1) << (L * 4)) - 1 }; 
}; 

std::cout << std::setw(4) << std::setfill('0') << std::hex << Foo<int,3>::result; 
+0

Ooohhh! Doux :) +1. Dommage que ce soit l'exécution;) –