C++ 如何将2位从一个int复制到另一个int?

C++ 如何将2位从一个int复制到另一个int?,c++,c,bit-manipulation,C++,C,Bit Manipulation,我有两个无符号整数:a和b(b是无符号整数指针)。我想将a的第8位和第9位复制到b的第2位和第3位(所有索引均以0为基础) 我就是这样做的: bool secondBit = (a & (1 << 8) ) ; bool thirdBit = (a & (1 << 9) ) ; if (secondBit) { *b |= (1u << 2); } if (thirdBit) { *b |= (1u <

我有两个无符号整数:
a
b
(b是无符号整数指针)。我想将
a
的第8位和第9位复制到
b
的第2位和第3位(所有索引均以0为基础)

我就是这样做的:

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

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

bool secondBit=(a&(1清除
*b
的相关位,并将其设置为
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 except 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);
*b=(*b&~0xC)|((a&0x300)>>6);
//这是000011100的“非”,换句话说,11110011
~0xC;
//这会将不需要的*b的位置零(b是指针)
*b&~0xC;//*b&11110011
//这将清除除所需位之外的所有a
a&0x300;
//将结果移到要在*b中设置的位置(位2和3)
((a&0x300)>>6);
//现在将位设置为*b,而不更改*b中的任何其他位
*b=(*b&~0xC)|((a&0x300)>>6);

在给定的代码中,它不复制位-它只是复制位。它应该这样做吗

*b &= ~0xC0;
先?然后

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

取决于您对“更好”的定义:


<>但是,C++中有一个类,也许它提供了一个不易出错的接口。它适合你的需要。

这里有一个更详细的方法来创建你正在寻找的结果和代码来测试操作。
#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");
}
#包括
无效打印位(整数n)
{
int i=31;
字符位[32];
对于(;i>=0;--i,n/=2)
{
位[i]=n%2;
}
对于(i=0;i<32;++i)
{
printf(“%d”,位[i]);
如果((i+1)%8==0)
{
putchar(“”);
}
}
}
int foo(int n1,int n2)
{
//将n1的第8位和第9位复制到n2的第2位和第3位
//(所有索引均以0为基础)。
//提取n1的第8位和第9位
int k1=0x00000300;
int r1=n1&k1;
//清除n2的第2位和第3位。
int k2=0xFFFFF9;
int r2=n2和k2;
//将n1的第8位和第9位向右移动6
//把它们放在第二和第三位。
//构造结果并返回。
返回(r1>>6)| r2;
}
int main(int argc,字符**argv)
{
int n1=atoi(argv[1]);
int n2=atoi(argv[2]);
printf(“输入n1:”);
打印位(n1);
printf(“\n”);
printf(“输入n2:”);
打印位(n2);
printf(“\n”);
int n3=foo(n1,n2);
printf(“结果:”);
打印位(n3);
printf(“\n”);
}
样本输出:

./test-19 251282 85 Input n1: 00000000 00000011 11010101 10010010 Input n2: 00000000 00000000 00000000 10000000 Result : 00000000 00000000 00000000 10000100 /测试-19 251282 85 输入n1:00000000000011 11010101 10010010 输入n2:00000000 00000000 00000000 10000000 结果:00000000 00000000 00000000 10000100
endian对这样的问题重要吗?a不是指针,只是一个INT。请注意,如果在
*b
中已经设置了位,那么它实际上不会重置位。如果这是您的意图,那么我认为您的代码比最上面的答案更清楚。我正试图对您编写的内容进行思考。您能解释一下,我们在这里做什么吗?@brainydexter(1)
0xC
12
,用二进制表示为
..01100
,按位求反
~/code>,其中
..10011
。使用
*b
*b
的第二位和第三位清除。(2)
0x300
0x100+0x200
,是2的第8次和第9次幂,这意味着它们代表第8位和第9位。使用
a
可以得到一个只有第8位和第9位的
a
。将这6位向右移动,使这些位位于第2位和第3位。(3)或者这两个结果是你想要的,所以我们分配(或者他分配)这对
*b
来说是有意义的。感谢@ThoAppelsin!@brainydexter的详细解释没问题,兄弟……但是上帝,我讨厌看到这样一个陈腐的直接答案,获得这么多的选票…+1,但我会先移动
a
,然后应用掩码(
*b=(*b&~0xC)|((a>>6)&0xC)
)因为在OR的两侧都有相同的掩码(对反转进行模化)。我不知道std::bitset的实现,但它的效率可能比“掩码、移位、取消掩码”方法低。或者更高效。我不知道,我没有测量:)很可能他实际应用程序中的实际差异太小,无法测量。真的,没有上下文很难说。这是不对的。第一行将把
*b
的所有位归零,位0和位1除外。您的意思是只将第2位和第3位的
~0xC
设置为零。通常,在掩码下插入是
dst=(dst&~mask)|(src&mask)
,其中
src
的位已经处于正确的位置,
mask
对于我们希望插入的每个位都有一个
1
,对于我们希望保留的每个位都有一个
0