2009-07-20 11 views
0

Ich bin auf der Suche nach einer schnellen Möglichkeit, eine Methode zum Zurückgeben einer Bitmaske basierend auf einer Nummer einzurichten. Grundsätzlich müssen 4 Ein-Bit-Eingaben vor der Nummer ausgegeben werden. Hier ist eine gute Idee von dem, was ich meine:Schnelle bitweise Frage in C++

foo (1); // gibt 0x000F foo (2) zurück; // gibt 0x00FF foo (3) zurück; // gibt 0x0FFF foo (4) zurück; // gibt 0xFFFF zurück

Ich könnte nur eine große switch-Anweisung verwenden, aber ich weiß nicht, wie breit der Eingangstyp im Voraus ist. (Dies ist eine Template-Funktion)

Hier war das erste, was ich versucht:

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; 
} 

aber es verbringt viel Zeit auf die maintenence tun for-Schleife. Irgendwelche clevere Möglichkeiten, das zu tun, an die ich nicht gedacht habe?

billy3

Antwort

9

Wie wäre es so etwas wie:

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

Nach ungefähr 10 Minuten, die herausfinden, warum es funktioniert, tritt A **! Vielen Dank! –

+0

@Charles Bailey, es dauerte länger als 10 Minuten, da meine Vorlagenprogrammierung ziemlich rostig ist und ich muss zugeben, dass es eine sehr schöne und elegante Lösung ist. Der Schlüssel ist zu erkennen, dass T (1) in einen Wert von 1 für den Typ umgewandelt wird, dann wird der eine so verschoben, dass er im nächsten Nibble ist, dann subtrahiere 1, um den 0xf zu erhalten. Ein Beispiel für unsigned short wäre also 0x0001, dann wäre es 0x0010, dann subtrahiere eins, um 0x000f zu erhalten. –

6

nur ein Array erstellen, dass jede Zahl an die entsprechende Bitmaske abbildet.

z.B. Karte [1] = 0x00F usw.

Dies wird die schnellste sein.

+0

Beat mich durch eine Sekunde. – GManNickG

+0

Stattdessen, wenn Sie Vektor verwenden, wird es nicht schneller sein, wie Sie v [1], v [2] usw. verwenden können, die eine konstante Zeitoperation sein werden? – Naveen

+0

Entschuldigung - Ich weiß nicht, wie groß das Array sein sollte, weil ich die Größe von() nicht kenne, wenn die Funktion aufgerufen wird. –

2

Wenn es nur Literale ist, könnten Sie auch dies tun zur Compile-Zeit durch eine Meta-Funktion. Hijacking Charles Idee:

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! Süß :) +1. Schade, es ist Laufzeit;) –