2010-12-13 3 views
4

Was ist der richtige Weg dazu? Sagen wir, ich habe ABCD und abcd und die Ausgabebits sollten etwas wie AaBbCcDd sein.Bei 2 16-Bit-Ints kann ich diese Bits verschachteln, um ein einzelnes 32-Bit-int zu bilden?

unsigned int JoinBits(unsigned short a, unsigned short b) { } 
+3

Ist dies eine Hausaufgabe ? Was hast du bisher versucht? – chrisaycock

+0

Verschieben eines der 16 Bit Werte nach oben. Sie müssen Ihren Prozessor Endianness kennen – kenny

+1

@kenny: Ich glaube nicht, dass Endianess ins Spiel kommt, da er Bitmuster aus beliebigem Speicher nicht interpretieren muss. – Lars

Antwort

4
#include <stdint.h> 

uint32_t JoinBits(uint16_t a, uint16_t b) { 
    uint32_t result = 0; 
    for(int8_t ii = 15; ii >= 0; ii--){ 
    result |= (a >> ii) & 1; 
    result <<= 1; 
    result |= (b >> ii) & 1; 
    if(ii != 0){ 
     result <<= 1; 
    } 
    } 
    return result; 
} 

auch hier auf ideone getestet: http://ideone.com/lXTqB.

0

Ohne mathematischen Trick zu nutzen wäre, meine erste naive Lösung sein, eine BitSet wie Datenstruktur zu verwenden, um die Ausgangszahl nach und nach zu berechnen. Dies würde Schleife über lg (a) + lg (b) Bits erfordern, die Ihnen die Komplexität geben würden.

3

Zuerst verbreiten Sie Ihre Bits:

unsigned int Spread(unsigned short x) 
{ 
    unsigned int result=0; 
    for (unsigned int i=0; i<15; ++i) 
    result |= ((x>>i)&1)<<(i*2); 
    return result; 
} 

Dann werden die beiden mit einem in Ihrer Funktion wie diese Offset fusionieren:

Spread(a) | (Spread(b)<<1); 
+0

scheint ein bisschen rund um mich ... erfordert unnötig zwei zusätzliche Funktionsaufrufe und zwei Schleifen – vicatcu

0

Mit etwas Bit-Manipulation durchaus möglich, aber der genaue Code hängt von der byte order der Plattform ab. Unter der Annahme, Little-Endian (das ist die häufigste ist), könnten Sie tun:

unsigned int JoinBits(unsigned short x, unsigned short y) { 
    // x := AB-CD 
    // y := ab-cd 

    char bytes[4]; 

    /* Dd */ bytes[0] = ((x & 0x000F) << 4) | (y & 0x000F); 
    /* Cc */ bytes[1] = (x & 0x00F0) | ((y & 0x00F0) >> 4); 
    /* Bb */ bytes[2] = ((x & 0x0F00) >> 4) | ((y & 0x0F00) >> 8); 
    /* Aa */ bytes[3] = ((x & 0xF000) >> 8) | ((y & 0xF000) >> 12); 

    return *reinterpret_cast<unsigned int *>(bytes); 
} 
+0

Ich verstehe, warum Sie diese Antwort (wegen Notation), aber ich glaube, er wollte echte bitweise Interleaving, nicht Nibble Interleaving. – vicatcu

+0

@vicatcu: Ich habe nicht daran gedacht, bis Sie es erwähnt haben - die Frage schlug stark anders vor; Ich konnte mir keine andere Möglichkeit vorstellen, "ABCD" als eine 16-Bit-Ganzzahl zu interpretieren. – casablanca

1

Wenn Sie echte bitweise Verschachtelung wollen, könnte die einfachste und elegante Art und Weise dies:

unsigned int JoinBits(unsigned short a, unsigned short b) 
{ 
    unsigned int r = 0; 

    for (int i = 0; i < 16; i++) 
     r |= ((a & (1 << i)) << i) | ((b & (1 << i)) << (i + 1)); 

    return r; 
} 
Verwandte Themen