21

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

例如,我有一个二进制 52504 作为 11001101000 11000,我想要前 6 位(从 LSB --> MSB 即 011000 十进制 24)位和其余 10 位(11001101000 十进制 820)。

同样,我希望这个函数过于笼统,无法提取给定“开始”和“结束”的特定位数(即与一些十进制值等效的位块)。

我检查了其他帖子,但这些帖子没有帮助,因为给定的功能并没有太笼统。

我需要一些适用于shortC 数据类型的东西。

编辑

我有大小为 2048 字节的短数组。其中每个像素为 10 位。所以我的 16 位由每个字节组成,有时占用 2 个像素数据,有时占用 3 个像素数据。

喜欢

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

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

依此类推......这种模式继续......所以,我只想提取每个像素并制作一个整个数组,让每个像素完全占据整个字节(16位),比如...... 1字节应该包含1 DATA PIXEL,其他 BYTE 应该包含整个 16 位的其他 PIXEL 值,依此类推。

4

8 回答 8

27

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

  • 获取N最低有效位需要在末尾构建一个位掩码N你这样做:((1 << N)-1). 1 << Nis :它在st 位置2 ^ N有一个,后面是全零。减一会给你你需要的面具。1N+1
  • 删除M最低有效位是一个简单的右移:k >> M

现在,您的从Mto剪切算法N变成了一个两步过程:您将原始值M位向右移动,然后AND使用掩码按位执行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;
}

此片段将位从 4(含)剪切到 16(独占),并bee在您运行时打印。位从零开始编号。

于 2012-04-10T14:14:29.433 回答
15
unsigned short extract(unsigned short value, int begin, int end)
{
    unsigned short mask = (1 << (end - begin)) - 1;
    return (value >> begin) & mask;
}

请注意,这[begin, end)是一个半开区间。

于 2012-04-10T14:14:45.713 回答
10

可以这样做:

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 给出结果。

于 2012-04-10T14:11:10.520 回答
3
//To get value from specific position 'pos' to 'pos+offset' in number 'value'

#define bitGet(value, offset, pos) (((1ull << offset) - 1) & (value >> (pos - 1)))

//Set value 'newval' from position 'pos' to 'pos+offset' in number 'value'

#define bitSet(value, offset, pos, newval)  \
(~(((1ull << offset) - 1) << (pos - 1)) & value) | ((((1ull << offset) - 1) & newval) << (pos - 1))
于 2019-07-07T18:57:04.873 回答
2

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. */ `

#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

Here, 255 = 11111111 and 62 = 00111110

于 2017-05-02T09:29:44.640 回答
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;
}
于 2012-10-16T14:01:28.557 回答
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
}

您可以添加参数以获取值或其他内容

于 2012-04-10T14:24:09.207 回答
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));
}
于 2013-02-06T21:30:54.457 回答