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

时间:2022-07-11 21:19:54

I need to extract specific part (no of bits) of a short data type in C.

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

For Example I have a binary of 52504 as 11001101000 11000 and I want First 6 ( FROM LSB --> MSB i.e 011000 decimal 24) bits and rest of 10 bits ( 11001101000 decimal 820).

例如,我有一个二进制的52504作为1100110100011000,而我要的是前6(从LSB—> MSB I)。e 011000 decimal 24)位和其余的10位(1100110decimal 820)。

Similarly I want this function to be too generalized to extract specific no of bits given "start" and "end" (i.e chunks of bits equivalent with some decimal value).

类似地,我希望这个函数过于一般化,不能提取给定“开始”和“结束”(I)的特定位的no。e块,相当于一个十进制值。

I checked other posts, but those were not helpful, as given functions are not too much generalized.

我检查了其他的帖子,但是这些都没有帮助,因为函数并不是太一般化。

I need something that can work for short data type of C.

我需要一些对短数据类型C有效的东西。

Edit

I am having the short array of size 2048 bytes. Where each Pixel is of 10 bits. So my 16 bit consisting each byte occupying some time 2 pixels data, sometimes 3 pixels data.

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

Like

就像

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

(像素:0,1)10比特+ 6位。

then ( PIXEL : 1,2,3 ) 4 BITS ( 1st pixels remaining bits ) + 10 BITS + 2 BITS.

然后(像素:1、2、3)4位(剩余1位)+ 10位+ 2位。

and so on ..this pattern continues ... So, all I want to extract each pixel and make an entire array of having each pixels to be occupied wholy in on WHOLE BYTE ( of 16 bits ) like.. 1 byte should contain 1 DATA PIXEL, the other BYTE should contain other PIXEL value in whole 16 bits and so on so forth.

等等. .这种模式继续下去……因此,我想提取每个像素并创建一个完整的数组,每个像素在整个字节(16位)中被占用。一个字节应该包含一个数据像素,另一个字节应该包含整个16位的其他像素值,以此类推。

7 个解决方案

#1


23  

There are two building blocks that you need to know to build this yourself:

有两个构建模块需要你自己去构建:

  • Getting N least significant bits requires constructing a bit mask with N ones at the end. You do it like this: ((1 << N)-1). 1 << N is 2 ^ N: it has a single 1 at the N+1st position, and all zeros after it. Subtracting one gives you the mask that you need.
  • 获得N个最不重要的位需要构造一个位掩码,最后有N个1。它是这样的:(1 < N)-1。1 < < N = 2 ^ N:它有一个1 N + 1的位置,和所有的0。减去1就得到了你需要的蒙版。
  • Dropping M least significant bits is a simple shift to the right: k >> M
  • 丢M个最不重要的位是向右移动:k >> M

Now your algorithm for cutting out from M to N becomes a two-step process: you shift the original value M bits to the right, and then perform a bit-wise AND with the mask of N-M ones.

现在,从M到N的分割算法变成了一个两步过程:将原始值M位移到右边,然后执行一个位元和N-M的掩码。

#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;
}

This fragment cuts out bits from 4, inclusive, to 16, exclusive, and prints bee when you run it. Bits are numbered from zero.

这个碎片从4,包括4,到16,排他,并且在你运行它时打印蜜蜂。位从0开始编号。

#2


11  

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

Note that [begin, end) is a half open interval.

注意[开始,结束]是半开放的间隔。

#3


6  

It can be done like this:

可以这样做:

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

where n is the original integer and value is the extracted bits.

其中n为原始整数,值为提取位。

The mask is constructed like this:

面具是这样构造的:

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

Now n is shifted right by start bits to align the desired bits to the left. Then a bitwise AND gives the result.

现在n通过开始位向右移位以使期望位向左对齐。然后按位给出结果。

#4


0  

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<last;i++)
       { mask+=1;
        mask<<1;}
      short int aux= myNr;
      aux=aux&mask; // only last bits are left
      //construct mask for first bits
      mask=0;
      for(int i=0;i<first;i++)
       { mask+=0x8000h;
        mask>>1;} 
      aux=myNr;  
      aux&=mask;
      aux>>last; // only first bits are left and shifted
}

you can add parameters to get the values out or something

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

#5


0  

// This is the main project file for VC++ application project 
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>

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) ) >> 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;
}

#6


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));
}

#7


0  

Although its a very old question, I would like to add a different solution. Using macros,

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

/* Here, startBit : start bit position(count from LSB) endBit : end bit position(count from LSB) .NOTE: endBit>startBit number : the number from which to extract bits maxLength:the total bit size of number. */ `

/*这里,startBit:开始位位置(从LSB开始计数):结束位位置(从LSB开始计数)。* /”

#include <stdio.h>
#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;
}

`

Output : Inputs : 1 5 255 32
Input number : 255
Output : 62

输出:输入:1 5 255 32输入号:255输出:62

Here, 255 = 11111111 and 62 = 00111110

这里,255 = 111111,62 = 001111

#1


23  

There are two building blocks that you need to know to build this yourself:

有两个构建模块需要你自己去构建:

  • Getting N least significant bits requires constructing a bit mask with N ones at the end. You do it like this: ((1 << N)-1). 1 << N is 2 ^ N: it has a single 1 at the N+1st position, and all zeros after it. Subtracting one gives you the mask that you need.
  • 获得N个最不重要的位需要构造一个位掩码,最后有N个1。它是这样的:(1 < N)-1。1 < < N = 2 ^ N:它有一个1 N + 1的位置,和所有的0。减去1就得到了你需要的蒙版。
  • Dropping M least significant bits is a simple shift to the right: k >> M
  • 丢M个最不重要的位是向右移动:k >> M

Now your algorithm for cutting out from M to N becomes a two-step process: you shift the original value M bits to the right, and then perform a bit-wise AND with the mask of N-M ones.

现在,从M到N的分割算法变成了一个两步过程:将原始值M位移到右边,然后执行一个位元和N-M的掩码。

#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;
}

This fragment cuts out bits from 4, inclusive, to 16, exclusive, and prints bee when you run it. Bits are numbered from zero.

这个碎片从4,包括4,到16,排他,并且在你运行它时打印蜜蜂。位从0开始编号。

#2


11  

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

Note that [begin, end) is a half open interval.

注意[开始,结束]是半开放的间隔。

#3


6  

It can be done like this:

可以这样做:

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

where n is the original integer and value is the extracted bits.

其中n为原始整数,值为提取位。

The mask is constructed like this:

面具是这样构造的:

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

Now n is shifted right by start bits to align the desired bits to the left. Then a bitwise AND gives the result.

现在n通过开始位向右移位以使期望位向左对齐。然后按位给出结果。

#4


0  

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<last;i++)
       { mask+=1;
        mask<<1;}
      short int aux= myNr;
      aux=aux&mask; // only last bits are left
      //construct mask for first bits
      mask=0;
      for(int i=0;i<first;i++)
       { mask+=0x8000h;
        mask>>1;} 
      aux=myNr;  
      aux&=mask;
      aux>>last; // only first bits are left and shifted
}

you can add parameters to get the values out or something

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

#5


0  

// This is the main project file for VC++ application project 
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>

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) ) >> 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;
}

#6


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));
}

#7


0  

Although its a very old question, I would like to add a different solution. Using macros,

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

/* Here, startBit : start bit position(count from LSB) endBit : end bit position(count from LSB) .NOTE: endBit>startBit number : the number from which to extract bits maxLength:the total bit size of number. */ `

/*这里,startBit:开始位位置(从LSB开始计数):结束位位置(从LSB开始计数)。* /”

#include <stdio.h>
#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;
}

`

Output : Inputs : 1 5 255 32
Input number : 255
Output : 62

输出:输入:1 5 255 32输入号:255输出:62

Here, 255 = 11111111 and 62 = 00111110

这里,255 = 111111,62 = 001111