Frage Wie kann ich 2 Bits von einem Int in einen anderen kopieren?


Ich habe zwei unsigned int-Nummern: a und b (b ist ein vorzeichenloser Zeiger). Ich möchte das 8. und 9. Bit kopieren a zum 2. und 3. Bit von b(Alle Indizes basieren auf 0).

So mache ich es:

 bool secondBit =  (a & (1 << 8) ) ;
 bool thirdBit =   (a & (1 << 9) ) ;

 if (secondBit) {
     *b |= (1u << 2);
 }
 if (thirdBit) {
     *b |= (1u << 3);

Erinnerung: b ist ein vorzeichenloser Zeiger.

Gibt es einen besseren Weg, dies zu tun?


5
2018-03-21 17:32


Ursprung


Antworten:


Löschen Sie die relevanten Bits von *b und setze sie auf die Bits, von denen du willst a:

*b = (*b & ~0xC) | ((a & 0x300) >> 6);

// This is the 'not' of 00001100, in other words, 11110011
~0xC;

// This zeros the bits of *b that you do not want (b being a pointer)
*b & ~0xC;   // *b & 11110011

//This clears all of a außer the bits that you want
a & 0x300;

// Shift the result into the location that you want to set in *b (bits 2 and 3)   
((a & 0x300) >> 6);

// Now set the bits into *b without changing any other bits in *b
*b = (*b & ~0xC) | ((a & 0x300) >> 6);

13
2018-03-21 17:36



Hängt von deiner Definition von "besser" ab :)

Aber, nun, da ist der std::bitset Klasse in C ++. Vielleicht entspricht es Ihren Anforderungen, indem es eine weniger fehleranfällige Schnittstelle bietet.


2
2018-03-21 17:39



Hier finden Sie eine ausführlichere Methode zum Erstellen des gewünschten Ergebnisses und einen Code zum Testen der Operation.

#include <stdio.h>

void printBits(int n)
{
   int i = 31;
   char bits[32];
   for ( ; i >= 0; --i, n /= 2 )
   {
      bits[i]= n % 2;
   }

   for ( i = 0; i < 32; ++i )
   {
      printf("%d", bits[i]);
      if ( (i+1)%8 == 0 )
      {
         putchar(' ');
      }
   }
}

int foo(int n1, int n2)
{
   // copy 8th and 9th bit of n1 to 2nd and 3rd bit of n2 
   // (all indices are 0 based).

   // Extract the 8th and 9th bits of n1
   int k1 = 0x00000300;
   int r1 = n1 & k1;

   // Clear the 2nd and 3rd bits of n2.
   int k2 = 0xFFFFFFF9;
   int r2 = n2 & k2;

   // Move the 8th and 9th bits of n1 by 6 to the right
   // to put them in 2nd and 3rd places.
   // Construct the result and return.
   return (r1 >> 6) | r2;
}

int main(int argc, char** argv)
{
   int n1 = atoi(argv[1]);
   int n2 = atoi(argv[2]);

   printf("Input n1: ");
   printBits(n1);
   printf("\n");

   printf("Input n2: ");
   printBits(n2);
   printf("\n");

   int n3 = foo(n1, n2);

   printf("Result  : ");
   printBits(n3);
   printf("\n");
}

Beispielausgabe:

./test-19 251282 85
Eingabe n1: 00000000 00000011 11010101 10010010
Eingabe n2: 00000000 00000000 00000000 10000000
Ergebnis: 00000000 00000000 00000000 10000100

0
2018-03-21 18:37



In dem angegebenen Code kopiert es die Bits nicht - es gehört nur ihnen. Sollte es tun

*b &= ~0xC0;

zuerst? Dann

*b |= ((a >> 6) & 0xC0);

0
2018-03-21 17:37