2016-07-11 45 views
2

Ich habe ein Array von neun Elementen und einer ganzen Zahl. Mit der Ganzzahl und Bitmaskierung möchte ich Informationen darüber speichern, ob ein Element des Arrays gültig ist.Einfache Möglichkeit, das n-te Array-Element zu bekommen, wenn alles, was ich habe, ist n^2

Also meine Frage ist: Gibt es einen einfacheren Weg als mit log2() von math.h von meiner Bitmaske zu meinem Array-Element Nummer zu bekommen? Zum Beispiel speichere ich foo2,foo4 und foo5 in mValue mit Bitmaskierung. Dann möchte ich das Array-Element an der Position foo2 = 2, das ist das zweite Bit, also das zweite Array-Element, das 34 ist. Aber der einzige Weg, an den ich denken kann, ist die log2(n) Funktion. Gibt es einen einfacheren mit Bitverschiebung?

Einfach gesagt, ich möchte, dies zu tun:

Ist das n-te Bit einer ganzen Zahl mValue auf 1 gesetzt? dann hol mir das n-te Element eines Arrays bar.

#include <math.h> 

const int foo1 = 1; 
const int foo2 = 2; 
const int foo3 = 4; 
const int foo4 = 8; 
const int foo5 = 16; 

int bar[9] = {23,34,82,8,7,0,23,19,20}; 
int mValue; 

void SetValue(int nVal) 
{ 
mValue = nVal; 
} 

bool IsElementValid(int nVal) 
{ 
return mValue & nVal; 
} 

int main() 
{ 
SetValue(foo2 | foo4 | foo5); 
IsElementValid(foo4); //true 
IsElementValid(foo5); //true 
IsElementValid(foo1); //false 

//access array element 1 with value foo2 (2) 
if(IsElementValid(foo2)) 
    printf("%d\n",  bar[log2(foo2)]); // output: '34' 
} 
+0

[diese Frage und Antworten] (http://stackoverflow.com/questions/757059/position-of-least-significant-bit-that-is-set) könnte für Sie nützlich sein – mvidelgauz

Antwort

2

Die übliche Idiom ist:

if (mValue & (1<<n)) { 
    return bar[n]; 
} 

EDIT: Aber wenn das einzige, was Sie wirklich haben, ist 2^n (und Sie können Ihre Logik um nicht drehen), können Sie immer noch die teuer vermeiden (und Doppel/float) Aufruf log2:

int bit_pos=0; 
unsigned int value = ...; // your input 

while (value>1) { 
    value >>= 1; 
    bit_pos++; 
} 

bit_pos enthält nun die Position des höchsten gesetzten Bit in value; Wenn value=2^n, wird es n sein.

Ich denke, es gibt elegantere und/oder noch schnellere Wege (ich würde es nicht an Intel oder anderen Firmen vorbeibringen, einen Assembler-Level-Befehl dafür zu erstellen), aber ich würde diese Dinge nur weiter optimieren, wenn nötig.

+0

Vielen Dank! aber das würde nur funktionieren, wenn ich "n" hätte. Aber was ich habe, ist '2^n'. – tzippy

+0

Wenn Sie nur nVal '2^n' haben (aber warum? Es macht keinen Sinn, normalerweise ist es ziemlich einfach,' n' herum zu behalten, oder Sie scannen die meisten Bits in einer Schleife, wo wieder Index halten ist einfach): Sie können überprüfen, ob Ihr Compiler Bitzählfunktion hat, zum Beispiel gcc hat 'int __builtin_popcount (unsigned int x)', also dann 'n = __builtin_popcount (nVal-1);' @tzippy – Ped7g

1
if (mValue & (1<<n)) { 
    printf("%d\n", bar[n]); 
} 

Ich bin ziemlich neu zu Bit Twiddling, aber das könnte nur funktionieren?