Pytanie Jak wyodrębnić określone bity z liczby w C?


Muszę wyodrębnić określoną część (liczbę bitów) z a short typ danych w C.

Na przykład mam binarne 52504 jako 11001101000 11000 i chcę pierwsze 6 (z LSB -> MSB, tj. 011000 dziesiętnie 24) bitów i resztę 10 bitów (11001101000 dziesiętnych 820).

Podobnie chcę, aby ta funkcja była zbyt uogólniona, aby wyodrębnić określoną liczbę bitów podanych jako "start" i "koniec" (tj. Fragmenty bitów równoważne pewnej wartości dziesiętnej).

Sprawdziłem inne posty, ale te nie były pomocne, ponieważ podane funkcje nie są zbytnio uogólnione.

Potrzebuję czegoś, na co można pracować short typ danych C.

Edytować

Mam krótką tablicę o rozmiarze 2048 bajtów. Gdzie każdy piksel ma 10 bitów. Tak więc mój 16-bitowy składający się z każdego bajtu zajmującego trochę czasu dane 2-piksele, czasami 3-piksele danych.

Lubić

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

następnie (PIXEL: 1,2,3)  4 BITS (bity pierwszego piksela) + 10 Bits + 2 BITS.

i tak dalej ... ten wzór jest kontynuowany ... Tak więc wszystko, co chcę, wyodrębnić każdy piksel i zrobić całą tablicę posiadania każdego piksela zajętego w całości w CAŁEGO BYTE (z 16 bitów), jak .. 1 bajt powinien zawierać 1 DATA PIXEL, a drugi BYTE powinien zawierać inną wartość PIXEL w całym 16 bitach i tak dalej.


17
2018-04-10 14:05


pochodzenie


czy mogę haz kod pls? - Vinicius Kamakura
po prostu ukryj to, co chcesz, tj. num & 0000000000111111 lub jeśli chcesz drugi koniec (num & 1111111111000000) >> 6 - Ferguzz
@hexa: prawdopodobnie masz rację, ale pytanie jest konstruktywne. Co robić...? Co robić...? - Nathan Fellman
Czy możesz zadać nieco bardziej szczegółowe pytanie? Najpierw mówisz, że chcesz podzielić dwie liczby na dwie części, potem mówisz, że chcesz określić początek i koniec, czy to oznacza, że ​​chcesz 3 numery na zewnątrz? Góra, środek i dół? - SpacedMonkey
Właściwie przetwarzam olbrzymi zbiór rozmiarów 2048 krótkich nośnych określonych wartości niektórych pikseli obrazu pobranego z kamery. Spójrz na edycję - Usman


Odpowiedzi:


Istnieją dwa bloki, które musisz znać, aby zbudować to samodzielnie:

  • Pierwsze N najmniej znaczące bity wymagają skonstruowania maska ​​bitowa z N jedne na końcu. Robisz to tak: ((1 << N)-1). 1 << N jest 2 ^ N: ma singiel 1 na N+1st position i wszystkie zera za nim. Odejmowanie jednego daje ci maskę, której potrzebujesz.
  • Rzut M najmniej znaczące bity to proste przesunięcie w prawo: k >> M

Teraz twój algorytm do wycinania M do N staje się procesem dwuetapowym: przesuwasz oryginalną wartość M bitów po prawej stronie, a następnie wykonaj trochę bitów AND z maską N-M te.

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

Fragment ten wycina fragmenty od 4, włącznie, do 16, wyłączności i odbitek bee kiedy go uruchomisz. Bity są ponumerowane od zera.


23
2018-04-10 14:14





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

Zauważ, że [begin, end) jest półotwartym odstępem.


12
2018-04-10 14:14





Można to zrobić w ten sposób:

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

gdzie n jest oryginalną liczbą całkowitą i value to wyodrębnione bity.

The mask jest skonstruowany w następujący sposób:

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

Teraz n jest przesunięty w prawo start bity do wyrównywania żądanych bitów w lewo. Następnie bitowe ORAZ daje wynik.


6
2018-04-10 14:11



zwraca błędne wartości .. Na przykład ... nie ma 150, a jego binarka to 0000000010010110 .. Potrzebuję od bitów początkowych (2--5) ... i sumują się z 22. Ale to w ogóle nie działa. - Usman
@Usman 22 jest prawe 5 bitów ... zrobiłeś to poprawnie? - 0605002
tak, oczywiście albo wybieracie pierwsze 5 bitów, albo zaczynacie od drugiego do szóstego taktu, jak mówiłem wcześniej ... liczy się do 22. Tak więc dałem początek = 1 i koniec = 5 lub dało się go zakończyć = 6. ... TO MUSI być 22. Ale nie wraca 22, zamiast tego zwraca 11 na początku = 1 i na końcu = 5. - Usman
Bit @Usman nr 2 to 1, więc wybór MUSI być nieparzystą liczbą! - 0605002
Nie rozumiem. Potrzebuję tylko niektórych fragmentów binarnych ... Myślę, że zredagowałem wpis, aby było bardziej zrozumiałe .. :-) - Usman


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
}

możesz dodać parametry, aby uzyskać wartości lub coś


0
2018-04-10 14:24





// 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
2017-10-16 14:01





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
2018-02-06 21:30





Chociaż jest to bardzo stare pytanie, chciałbym dodać inne rozwiązanie. Korzystanie z makr,

/ * Tutaj,    startBit: start bit position (licznik od LSB)    endBit: końcowa pozycja bitu (liczona od LSB). UWAGA: endBit> startBit    liczba: liczba, z której należy wyodrębnić bity    maxLength: całkowity bitowy rozmiar liczby. * / `

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

`

Wyjście:  Wejścia: 1 5 255 32
 Numer wejścia: 255
Wyjście: 62

Tutaj 255 = 11111111 i 62 = 00111110


0
2018-05-02 09:29