LINUX.ORG.RU

Получить данные из битовой структуры.


0

1

Вопрос в следующем. есть структура данных полученная от контроллера
32 бита.
первые 8 бит это заголовок. получить не проблема.
а вот дальше идут два значения по 12 бит.

это байтовое преставление в битах
********|********|********|********

********|******** ****|**** ********| вот как то так.
Нужно получить значение в этих 12 битах.

Подозреваю что надо за счёт битовых сдвигов организовывать.
Буду очень благодарен за любую наводку чтоб не терять время и не изобретать «велосипед».

на Си



Последнее исправление: friniz (всего исправлений: 1)

код не мой, и даже алгоритм может быть говном, но работает:

        /// <summary>
        /// Read packed integers from buffer. For example - read 10-bit integers, that placed one by one with no gap
        /// </summary>
        /// <param name="pBuffer">Buffer to read</param>
        /// <param name="pFrom">Read from this index</param>
        /// <param name="pIntCount">How many N-bit integers would be readed</param>
        /// <param name="pBitPerInt">Count of bits per one integer (from 8 to 32)</param>
        /// <returns>Array of readed integers</returns>
        public static int[] ReadPackedIntegers(byte[] pBuffer, int pFrom, int pIntCount, int pBitPerInt)
        {
            //can we do it?
            if (pBitPerInt > 32) throw new ArgumentException("This method can operate only up to 32 bit integers!");
            //check buffer length
            if (pIntCount * pBitPerInt > (pBuffer.Length - pFrom) * 8)
                throw new ArgumentException("Buffer is too short for contain " + pIntCount.ToString() + " of " + pBitPerInt.ToString() + " bits numbers");
            //result
            int[] res = new int[pIntCount];

            int ri = 0;//res index
            int pbi = pFrom;//pBuffer index
            int msl = 8;//shift mask left
            int nsr = pBitPerInt > 7 ? 0 : 8 - pBitPerInt;//number shift right
            int b2rc = 8 - nsr;//bits to read from byte
            int b2rfn = pBitPerInt;//bits to read for number
            while (ri < pIntCount)
            {
                unchecked
                {
                    //read data
                    res[ri] |= ((pBuffer[pbi] & ~((int)0xFFFFFFFF << msl)) >> nsr);
                }
                b2rfn -= b2rc;//how bits we read
                //free place for next bits
                if (b2rfn == 0)//if requested number collected
                {
                    ri++;//step to next
                    b2rfn = pBitPerInt;
                }
                //we'll get partial result at next step
                if (nsr < pBitPerInt)
                {
                    //eat last bit
                    if (nsr == 0)
                    {
                        nsr = 8;
                        b2rc = b2rfn > 8 ? 8 : b2rfn;
                        pbi++;
                    }
                    else
                    {
                        b2rc = nsr;
                    }
                }
                else
                {
                    b2rc = pBitPerInt;
                }
                msl = nsr;
                nsr -= b2rc;
                if(b2rfn != pBitPerInt)
                    res[ri] <<= b2rc;
            }
            return res;
        }

за C# не бить, производственная необходимость.

dib2 ★★★★★
()

> Подозреваю что надо за счёт битовых сдвигов организовывать.

Как-то так:
unsigned a1 = (((unsigned)c[1]) << 4) + (c[2] >> 4);
unsigned a2 = (((unsigned)c[2] & 0xf) << 8) + c[3];

Буду очень благодарен за любую наводку чтоб не терять время и не изобретать «велосипед».


Надо просто открыть спроавочник по Си и выучить раз и навсегда операции сдвига.

geekless ★★
()

struct и union поддерживают битовые поля как бы.


union {
  struct { byte a, b , c, d } bytes;
  struct { byte a; word b: 12; word c: 12; } myReprentation;
}

bga_ ★★★★
()

man C

P.S. Это (битовые поля) изначально в C встроены и любом букваре по C описаны.

Led ★★★☆☆
()

string из gnuutils

enep ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.