Frage

Lassen Sie uns sagen, dass ich ein Byte mit sechs unbekannten Werte haben:

???1?0??

und ich möchte Bits tauschen 2 und 4 ( ohne eine der ? Werte zu ändern):

???0?1??

Aber wie würde ich tun dies in eine Operation in C?

Ich bin die Durchführung dieser Operation tausende Male pro Sekunde auf einem Mikrocontroller so Leistung die höchste Priorität ist.

Es wäre gut, um diese Bits „umschalten“. Auch wenn dies als Vertauschen der Bits nicht gleich ist, Makeln würde für meine Zwecke gut funktionieren.

War es hilfreich?

Lösung

Versuchen:

x ^= 0x14;

, dass beide Bits schaltet. Es ist ein wenig unklar, in Frage, wie Sie erste Erwähnung Swap- und dann ein Toggle-Beispiel. Wie auch immer, um die Bits zu tauschen:

x = precomputed_lookup [x];

Dabei gilt precomputed_lookup ein 256-Byte-Array ist, könnte der schnellste Weg sein, hängt es von der Speichergeschwindigkeit in Bezug auf die Prozessorgeschwindigkeit. Ansonsten ist es:

x = (x & ~0x14) | ((x & 0x10) >> 2) | ((x & 0x04) << 2);

EDIT:. Einige weitere Informationen über Bits Makeln

Wenn Sie XOR (^) zwei Integer-Werte zusammen, die xor auf Bit-Ebene durchgeführt wird, wie folgt aus:

for each (bit in value 1 and value 2)
   result bit = value 1 bit xor value 2 bit

, so dass das Bit 0 des ersten Wertes wird mit dem Bit 0 des zweiten Wertes EXOR'ed, Bit 1 Bit mit 1 und so weiter. Die XOR-Operation wirkt sich nicht auf die anderen Bits in dem Wert. In der Tat ist es ein Parallel-Bit-xor auf viele Bits.

an der Wahrheitstabelle der Suche nach xor, werden Sie sehen, dass XOR-Verknüpfung ein wenig mit dem Wert ‚1‘ wirksam schaltet das Bit.

 a  b a^b
 0  0  0
 0  1  1
 1  0  1
 1  1  0

So wechseln Bits 1 und 3, eine binäre Zahl mit einem schreiben, wo Sie das Bit wollen wechseln und eine Null in dem Sie den Wert unverändert lassen wollen:

00001010

zu hex konvertieren: 0x0a. Sie können so viele Bits wechseln, wie Sie wollen:

0x39 = 00111001

schaltet die Bits 0, 3, 4 und 5

Andere Tipps

Sie können nicht "swap" zwei Bits (das heißt die Bits ändern Orten, nicht Wert) in einem einzigen Befehl mit Bit-Fiedeln.

Der optimale Ansatz, wenn Sie wirklich wollen, um sie tauschen ist wahrscheinlich eine Lookup-Tabelle. Dies gilt für viele ‚ungeschickt‘ Transformationen.

BYTE lookup[256] = {/* left this to your imagination */};

for (/*all my data values */) 
  newValue = lookup[oldValue];

Das folgende Verfahren ist nicht ein einziger C-Befehl, es ist nur eine andere Bit Hantieren Methode. Die Methode wurde von vereinfacht Swapping einzelne Bits mit XOR .

Wie in Roddy Antwort angegeben , wäre eine Lookup-Tabelle am besten. Ich schlage vor, dies nur, wenn Sie nicht wollen, zu verwenden. Dies wird in der Tat Bits tauscht auch, nicht nur hin- und herzuschalten (das ist, was auch immer in Bit 2 in 4 und umgekehrt sein wird).

  • b: Ihre ursprünglichen Wert - ??? 1 0 ?? zum Beispiel
  • x: nur ein temporärer
  • r: das Ergebnis

    x = ((b >> 2) ^ (b >> 4)) & 0x01
    r = b ^ ((x << 2) | (x << 4))

Kurze Erklärung: Nutzen Sie die zwei Bits, die Sie wollen, zu betrachten und XOR sie, speichern Sie den Wert auf x. Durch die Verlagerung dieser Wert wieder auf die Bits 2 und 4 (und OR-zusammen) erhalten Sie eine Maske, die, wenn sie mit b XORed zurück Ihre beiden ursprünglichen Bits tauschen. Die folgende Tabelle zeigt alle möglichen Fälle.

bit2: 0 1 0 1  
bit4: 0 0 1 1  
x   : 0 1 1 0   <-- Low bit of x only in this case 
r2  : 0 0 1 1  
r4  : 0 1 0 1

Ich habe das nicht vollständig testen, aber für die wenigen Fälle, habe ich versucht, schnell schien es zu arbeiten.

Diese

möglicherweise nicht optimiert werden, aber es sollte funktionieren:

unsigned char bit_swap(unsigned char n, unsigned char pos1, unsigned char pos2)
{
    unsigned char mask1 = 0x01 << pos1;
    unsigned char mask2 = 0x01 << pos2;
   if ( !((n & mask1) != (n & mask2)) )
        n ^= (mask1 | mask2);
    return n;
}

Die Funktion unten wird Swap-Bits 2 und 4. Sie können diese verwenden, um eine Lookup-Tabelle vorauszuberechnen, falls erforderlich (so dass Swapping eine einzige Operation wird):

unsigned char swap24(unsigned char bytein) {
    unsigned char mask2 = ( bytein & 0x04 ) << 2;
    unsigned char mask4 = ( bytein & 0x10 ) >> 2;
    unsigned char mask  = mask2 | mask4 ;
    return ( bytein & 0xeb ) | mask;
}

Ich schrieb jede Operation in einer separaten Zeile es deutlicher zu machen.

Sagen Sie Ihr Wert x heißt, x = ??? 1? 0 ??

Die beiden Bits können durch diesen Vorgang umgeschaltet werden:

x = x ^ ((1<<2) | (1<<4));
#include<stdio.h>

void printb(char x) {
    int i;
    for(i =7;i>=0;i--) 
        printf("%d",(1 & (x >> i)));
    printf("\n");
}

int swapb(char c, int p, int q) {
    if( !((c & (1 << p)) >> p) ^ ((c & (1 << q)) >> q) )
        printf("bits are not same will not be swaped\n");
    else {
        c = c ^ (1 << p);
        c = c ^ (1 << q);
    }
    return c;
}

int main() 
{
    char c = 10;
    printb(c);
    c = swapb(c, 3, 1);
    printb(c);
    return 0;
}
void swap_bits(uint32_t& n, int a, int b) {
    bool r = (n & (1 << a)) != 0;
    bool s = (n & (1 << b)) != 0;

    if(r != s) {
        if(r) {
            n |= (1 << b);
            n &= ~(1 << a);
        }
        else {
            n &= ~(1 << b);
            n |= (1 << a);
        }
    }
}

n die ganze Zahl Sie werden möchten, tauschte in, a und b sind die Positionen (Indizes) der Bits, die Sie ausgelagert werden soll, von dem weniger signifikanten Bit zu zählen und ausgehend von Null.

Mit Ihrem Beispiel (n = ???1?0??), dann würden Sie die Funktion aufrufen wie folgt:

swap_bits(n, 2, 4);

Begründung : Sie müssen nur die Bits tauschen, wenn sie verschieden sind (deshalb r != s). In diesem Fall ist einer von ihnen 1 und der andere ist 0. Danach wird bemerken nur genau ein Bit gesetzt Betrieb und ein Bit klar Betrieb machen wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top