it-swarm.com.de

Wie kann man bestimmte Bits aus einer Zahl in C extrahieren?

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.

Bearbeiten

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.

18
Usman

Es gibt zwei Bausteine, die Sie wissen müssen, um dies selbst zu erstellen:

  • Das Erhalten von 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+1st-Position und alle Nullen danach. Wenn Sie eine davon abziehen, erhalten Sie die Maske, die Sie benötigen.
  • Das Ablegen von 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.

24
dasblinkenlight
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.

13
Andreas Brinck

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.

7
0605002
//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))
0
Neeta
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

0
CosminO
// 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;
}
0
kapilddit

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

0
PraveenMax
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));
}
0
user1596193