2010-09-21 1 views
10

Ho un arbitrario binario a 8 bit numero esempio, 11101101Scambio coppia di bit in un byte

devo scambiare tutta la coppia di bit come:

Prima scambio: 11-10-11-01 Dopo aver scambiato : 11-01-11-10

Mi è stato chiesto in un'intervista!

+0

Che cosa è la questione? – JamesM

+0

Ci scusiamo per la prima risposta che ho dato se ti ha confuso. Ho letto completamente il tuo prima/dopo sbagliato. – colithium

+0

@JamesM: Ci scusiamo, se non è evidente ma la domanda è: in un byte, accoppiare i bit per esempio, se il byte è 10101100 allora l'abbinamento dei bit sarà simile a '' 10 - 10 - 11 - 00'. Ora, se scambiamo le singole coppie, diventerebbe - 01 - 01 - 11 - 00'. Avevo bisogno del meccanismo per implementare lo swapping – RaviPathak

risposta

31

In pseudo-codice:

x = ((x & 0b10101010) >> 1) | ((x & 0b01010101) << 1) 

Agisce manipolazione dei bit bassi ed alti bit di ciascun bit-pair separatamente e quindi combinando il risultato:

  • L'espressione x & 0b10101010 estrae l'alto bit da ciascuna coppia, quindi >> 1 lo sposta nella posizione di bit basso.
  • Analogamente, l'espressione (x & 0b01010101) << 1 estrae il bit basso da ciascuna coppia e lo sposta nella posizione del bit più alto.
  • Le due parti vengono quindi combinate usando bit per bit-OR.

Dal momento che non tutte le lingue consentono di scrivere direttamente letterali binari, si potrebbe scrivere loro in ad esempio esadecimale:

 
Binary  Hexadecimal Decimal 
0b10101010 0xaa   170 
0b01010101 0x55   85 
+3

Dato che non tutte le lingue rispettano il modello 0b ..., probabilmente vale la pena notare che sono rispettivamente 0xAA e 0x55 in esadecimale. – userx

+0

@userx: +1 Sì, vale sicuramente la pena notare. Aggiunto. –

+0

Grazie Marco. Questo è un metodo fantastico! – RaviPathak

0
b = (a & 170 >> 1) | (a & 85 << 1) 
+2

Questo è completamente illeggibile; inoltre, è inefficiente e persino errato per i casi limite. Dividere per due non equivale a uno spostamento a destra di un bit per i numeri negativi. – tdammers

+0

uguale a quello di risposta di tdammers ma che è più pulito e esplicitamente binario, mentre si utilizzano numeri decimali. – vulkanino

+0

-1 molto illeggibile – Tomas

-5

avrei primo codice è 'longhand' - vale a dire in varie ovvie, fasi esplicite, e l'uso che per verificare che i test di unità che avevo in essere funzionavano correttamente, quindi muovono solo a più soluzioni esoteriche di manipolazione dei bit se avevo bisogno di prestazioni (e che le prestazioni extra venivano fornite da tali improvvisazioni)

Codice per le persone prima, computer secondo.

+1

-1 che non risponde alla domanda – Tomas

5
  1. fare due maschere di bit, uno contenente tutte le persino bit e uno contenente i bit non uniformi (10101010 e 01010101).
  2. Utilizzare bit per bit e filtrare l'input in due numeri, uno con tutti i bit pari azzerati, l'altro con tutti i bit non uniformi azzerati.
  3. Spostare il numero che contiene solo bit pari a un bit a sinistra e l'altro a destra sulla punta
  4. Utilizzare bit per bit o combinarli di nuovo.

Esempio per 16 bit (codice non effettivo):

short swap_bit_pair(short i) { 
    return ((i & 0101010110101010b) >> 1) | ((i & 0x0101010101010101b) << 1)); 
} 
+0

Um .. Penso che tu intenda 0xAA invece di 0x10101010 (0xAA essendo 10101010 in binario) e 0x55 invece di 0x01010101. Bene per un byte comunque. 0xAAAA e 0x5555 rispettivamente per un corto. – userx

+0

Sì, ho già modificato lo pseudocodice C-like per usare invece il binario. La domanda originale indica comunque 8 bit, quindi ... – tdammers

0

La soluzione più elegante e flessibile, come altri hanno già detto, per applicare una maschera 'pettine' ad entrambi i bit pari e dispari separatamente e poi, dopo averli spostati a sinistra e a destra rispettivamente in un punto per combinarli usando bit a bit o.

Un'altra soluzione che potresti voler sfruttare sfrutta le dimensioni relativamente ridotte del tuo tipo di dati.È possibile creare una tabella di ricerca di 256 valori che viene inizializzata staticamente ai valori che si desidera come uscita per il vostro input:

const unsigned char lookup[] = { 0x02, 0x01, 0x03, 0x08, 0x0A, 0x09, 0x0B ... 

Ogni valore è posto nella matrice per rappresentare la trasformazione dell'indice. Quindi, se fate questo:

unsigned char out = lookup[ 0xAA ]; 

out conterrà 0x55

Questo è più ingombrante e meno flessibile rispetto al primo approccio (cosa succede se si desidera spostare da 8 bit a 16?), Ma non ha l'approccio che sarà misurabilmente più veloce se si esegue un gran numero di queste operazioni.

0

Supponiamo che il numero sia num.

In primo luogo trovare la anche po 'di posizione:
num & oxAAAAAAAA

Secondo passo trovare il bit strana posizione:
num & ox55555555

3 ° gradino cambiare posizione strana posizione di ancora po' la posizione e anche po 'posizione a posizione dispari bit:
Even = (num & oxAAAAAAAA)>>1
Odd = (num & 0x55555555)<<1

Ultimo passo ... result = Even | Odd

risultato Stampa