如何从C中的数字中提取特定位?

我需要在C中提取short数据类型的特定部分(没有位)。

例如,我的二进制52504为11001101000 11000,我想要前6(FROM LSB – > MSB即011000十进制24)位和其余10位(11001101000十进制820)。

类似地,我希望这个函数过于通用,不能提取给定“start”和“end”的特定位数(即位块等效于一些十进制值)。

我检查了其他post,但那些没有帮助,因为给定的function并没有太多的概括。

我需要一些可以用于C的short数据类型的东西。

编辑

我有2048字节的短数组。 每个像素为10位。 所以我的16位组成每个字节占用一些时间2像素数据,有时3像素数据。

喜欢

(PIXEL:0,1)10 BITS + 6 BITS

然后(PIXEL:1,2,3)4 BITS(剩余第1个像素位)+ 10个BITS + 2个BITS。

等等..这个模式继续……所以,我想要提取每个像素并制作一个整个数组,让每个像素都被占用在整个字节(16位)上,如… 1字节应该包含1 DATA PIXEL,另一个BYTE应该包含整个16位的其他PIXEL值,依此类推。

您需要了解两个构建块才能自行构建:

  • 获得N最低有效位需要在结尾处构造具有N个的位掩码 。 你这样做: ((1 << N)-1)1 << N2 ^ N :它在N+1 st位置有一个1 ,并且在它之后全部为零。 减去一个可以为你提供所需的面具。
  • 丢弃M最低有效位是向右的简单移位: k >> M

现在,用于从M切换到N算法变为两步过程:将原始值M位向右移动,然后使用NM的掩码执行逐位AND

 #define LAST(k,n) ((k) & ((1<<(n))-1)) #define MID(k,m,n) LAST((k)>>(m),((n)-(m))) int main() { int a = 0xdeadbeef; printf("%x\n", MID(a,4,16)); return 0; } 

这个片段将从4(包括4和16)的位切除到16,独占,并在运行时打印bee 。 位从零开始编号。

 unsigned short extract(unsigned short value, int begin, int end) { unsigned short mask = (1 << (end - begin)) - 1; return (value >> begin) & mask; } 

请注意, [begin, end)是半开的间隔。

它可以这样做:

 mask = ~(~0 << (end - start + 1)); value = (n >> start) & mask; 

其中n是原始整数, value是提取的位。

mask构造如下:

 1. ~0 = 1111 1111 1111 1111 1111 1111 1111 1111 2. ~0 << (end - start + 1) = 1111 1111 1111 1111 1100 0000 0000 0000 // assuming we are extracting 14 bits, the +1 is added for inclusive selection // ensure that end >= start 3. ~(~0 << (end - start + 1)) = 0000 0000 0000 0000 0011 1111 1111 1111 

现在n通过start位向右移位以将所需位对齐到左侧。 然后按位AND给出结果。

 void f(short int last, short int first, short int myNr){ //construct mask for last bits short int mask=0; for(int i=0;i>1;} aux=myNr; aux&=mask; aux>>last; // only first bits are left and shifted } 

你可以添加参数来获取值或其他东西

 // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using  using namespace System; void fun2(int *parr) { printf(" size of array is %d\n",sizeof(parr)); } void fun1(void) { int arr[100]; printf(" size of array is %d\n",sizeof(arr)); fun2(arr); } int extractBit(int byte, int pos) { if( !((pos >= 0) && (pos < 16)) ) { return 0; } return ( ( byte & (1<> pos); } int extractBitRange(int byte, int startingPos, int offset) { if( !(((startingPos + offset) >= 0) && ( (startingPos + offset) < 16)) ) { return 0; } return ( byte >> startingPos ) & ~(0xff << (offset + 1)); } int _tmain() { // TODO: Please replace the sample code below with your own. int value; signed int res,bit; signed int stPos, len; value = 0x1155; printf("%x\n",value); //Console::WriteLine("Hello World"); //fun1(); for(bit=15;bit>=0;bit--) { res =extractBit(value,bit); printf("%d",res); } stPos = 4; len = 5; res = extractBitRange(value, stPos, len); printf("\n%x",res); return 0; } 
 unsigned int extract_n2mbits(unsigned int x, int n, int m) { unsigned int mask, tmp; if (n < m) { n = n + m; m = n - m; n = n - m; } mask = 1 << (n - m + 1); tmp = m; while (tmp > 1) { mask = mask << 1 | 1 << (n - m + 1); tmp = tmp - 1; } return ((x & mask) >> (n - m + 1)); } 

虽然这是一个非常古老的问题,但我想补充一个不同的解决方案。 使用宏,

/ *这里,startBit:起始位位置(从LSB开始计数)endBit:结束位位置(从LSB开始计数)。注意:endBit> startBit number:从中提取位的数字maxLength:数字的总位数。 * /`

 #include  #define getnbits(startBit,endBit,number,maxLength) \ ( number & ( (~0U >> (maxLength-endBit)) & (~0U << startBit) ) ) int main() { unsigned int num=255; unsigned int start=1,end=5,size=sizeof(num)*8; printf("Inputs : %d %d %d %d \n ",start,end,num,size); printf("Input number : %d\n",num); if(end>start) { int result = getnbits(start,end,num,size-1); printf("Output : %u\n\n",result); } else printf("Error : EndBit is smaller than starBit!\n\n"); return 0; } 

`

输出:输入:1 5 255 32
输入数量:255
输出:62

这里,255 = 11111111和62 = 00111110