Ich muss einen bestimmten Teil (keine Bits) eines Datentyps short
in C extrahieren.
Zum Beispiel habe ich eine Binärzahl von 52504 als 11001101000 11000 und ich möchte zuerst 6 Bits (von LSB -> MSB, dh 011000 Dezimal 24) Bits und den Rest von 10 Bits (11001101000 Dezimal 820).
In ähnlicher Weise möchte ich, dass diese Funktion zu verallgemeinert ist, um eine bestimmte Anzahl von Bits zu extrahieren, die "Anfang" und "Ende" erhalten (d. H. Stücke von Bits, die mit einem Dezimalwert äquivalent sind).
Ich habe andere Beiträge überprüft, aber diese waren nicht hilfreich, da die angegebenen Funktionen nicht zu stark verallgemeinert sind.
Ich brauche etwas, das für short
Datentyp von C arbeiten kann.
Ich habe das kurze Array der Größe 2048 Bytes. Wo jedes Pixel aus 10 Bits besteht. Also besteht mein 16-Bit-Byte aus zwei Pixeln, manchmal 3 Pixeln.
Mögen
(PIXEL: 0,1) 10 BITS + 6 BITS
dann (PIXEL: 1,2,3) 4 BITS (1. Pixel verbleibende Bits) + 10 BITS + 2 BITS.
und so weiter ... dieses Muster wird fortgesetzt ....__ Alles, was ich möchte, um jedes Pixel zu extrahieren und ein ganzes Array von Pixeln zu machen, die auf Whole Byte (von 16 Bits) belegt sind, wie ...__ Das .1-Byte sollte 1 DATA PIXEL enthalten, das andere BYTE sollte andere PIXEL-Werte in ganzen 16 Bit enthalten und so weiter.
Es gibt zwei Bausteine, die Sie wissen müssen, um dies selbst zu erstellen:
N
niedrigstwertigen Bits erfordert das Erstellen einer Bit-Maske mit N
-Einsen am Ende. Sie machen es so: ((1 << N)-1)
. 1 << N
ist 2 ^ N
: Er hat einen einzelnen 1
an der N+1
st-Position und alle Nullen danach. Wenn Sie eine davon abziehen, erhalten Sie die Maske, die Sie benötigen.M
niedrigstwertigen Bits ist eine einfache Verschiebung nach rechts: k >> M
Nun wird Ihr Algorithmus zum Ausschneiden von M
auf N
zu einem zweistufigen Prozess: Sie verschieben die ursprünglichen Wert M
-Bits nach rechts und führen dann eine bitweise AND
mit der Maske von N-M
-Eins aus.
#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;
}
Dieses Fragment schneidet Bits von 4 (einschließlich) bis 16 (exklusiv) ab und druckt bee
, wenn Sie es ausführen. Bits sind von Null aus nummeriert.
unsigned short extract(unsigned short value, int begin, int end)
{
unsigned short mask = (1 << (end - begin)) - 1;
return (value >> begin) & mask;
}
Beachten Sie, dass [begin, end)
ein halboffenes Intervall ist.
Es kann so gemacht werden:
mask = ~(~0 << (end - start + 1));
value = (n >> start) & mask;
dabei ist n
die ursprüngliche Ganzzahl und value
die extrahierten Bits.
Die mask
ist folgendermaßen aufgebaut:
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
Jetzt wird n
um start
-Bits nach rechts verschoben, um die gewünschten Bits nach links auszurichten . Ein bitweises AND ergibt das Ergebnis.
//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))
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
}
sie können Parameter hinzufügen, um die Werte oder etwas herauszuholen
// 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;
}
Obwohl es eine sehr alte Frage ist, möchte ich eine andere Lösung hinzufügen. Makros verwenden,
/*Hier, startBit: Startbitposition (Zählung von LSB) endBit: Endbitposition (Zählung von LSB) .NOTE: endBit> startBit number: die Nummer, aus der die Bits extrahiert werden sollen maxLength: die Gesamtbitgröße der Zahl. */ `
#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;
}
`
Ausgabe: Eingänge: 1 5 255 32
Eingangsnummer: 255
Ausgabe: 62
Hier ist 255 = 11111111 und 62 = 00111110
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));
}