[英]How to extract specific bits from a number in C?
我需要提取 C 中short
數據類型的特定部分(位數)。
例如,我有一個二進制 52504 作為 11001101000 11000,我想要前 6(從 LSB --> MSB 即 011000 十進制 24)位和 rest 的 10 位(11001101000 十進制 820)。
同樣,我希望這個 function 過於籠統,無法提取給定“開始”和“結束”的特定位數(即,與某個十進制值等效的位塊)。
我檢查了其他帖子,但這些都沒有幫助,因為給定的功能並沒有太籠統。
我需要一些可以用於 C short
數據類型的東西。
我有一個大小為 2048 字節的短數組。 其中每個像素為 10 位。 所以我的 16 位由每個字節組成,有時占用 2 個像素數據,有時占用 3 個像素數據。
像
(像素:0,1)10 位 + 6 位
然后(像素:1,2,3)4 位(第一個像素剩余位)+ 10 位 + 2 位。
等等..這種模式繼續......所以,我只想提取每個像素並制作一個完整的數組,讓每個像素完全占據整個字節(16位)就像.. 1字節應該包含1 DATA PIXEL,其他BYTE 應包含其他PIXEL 值整16 位等等。
要自己構建它,您需要了解兩個構建塊:
N
個最低有效位需要構建一個末尾有N
個 1 的位掩碼。 你這樣做: ((1 << N)-1)
。 1 << N
是2 ^ N
:它在N+1
st position 處有一個1
,其后全為 0。 減去一個給你你需要的掩碼。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(含)剪切到 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
是原始的 integer, 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
位,以便將所需的位向左對齊。 然后按位與給出結果。
//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))
盡管這是一個非常古老的問題,但我想添加一個不同的解決方案。 使用宏,
/* 這里,startBit:起始位位置(從LSB算起) endBit:結束位位置(從LSB算起) 注意:endBit>startBit number:要提取的位的個數 maxLength: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:輸入:1 5 255 32
輸入數:255
Output: 62
在這里,255 = 11111111 和 62 = 00111110
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
}
您可以添加參數以獲取值或其他內容
// 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;
}
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));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.