Каков эффективный метод определения размера типа, заданного в виде двоичной строки? - PullRequest
3 голосов
/ 30 сентября 2011

Во-первых, давайте предположим, что я отсортировал endian и знаю размер типов априори.

Вот что я делаю: у меня есть функция bs2i(char *bitStr), которая принимает массив символов, представляющий двоичный файл со знаком char / short / int / long. Массив может быть любой длины <= <code>sizeof(long long).

Что я хочу сделать, так это взять bitStr [0] и установить его в качестве знакового бита, чтобы он не усекался, если я сделаю что-то вроде char val = bs2i("111"). В этом случае функция должна возвращать -125, поскольку биты будут установлены как «000 ... 00010000011». Для этого мне нужно знать, какой длины должен быть последний тип, чтобы я мог сдвинуть msb в нужное место.

Это то, что я имею до сих пор:

size_t size = (((strlen(bitStr)-1)>>3)+1)<<3;

Но я только что понял, что работает только для символов и шорт. Например, строка длиной 17 должна возвращать размер 32, но возвращать только 24 с этим методом. Есть ли эффективный способ определить правильную длину?

Для справки, вот полная функция:

long long bs2i(char *bitStr) {
    long long val = 0l;
    size_t len = (((strlen(bitStr) - 1) >> 3) + 1) << 3;
    char msb = *bitStr & 1;
    bitStr++;
    while (*bitStr) {
        val = (val << 1l) | (*bitStr & 1);
        bitStr++;
    }
    val = (msb << len-1l) | val; /* Use MSB as sign bit */

    return val;
}

Бонусные баллы, я думаю, если есть хороший способ сделать это, не требующий априорного знания размеров шрифта.

Ответы [ 2 ]

4 голосов
/ 30 сентября 2011

Звучит так, как будто вы хотите найти наименьшую степень двойки, кратную 8 числу битов, которые бы уместились в столько разрядов, сколько символов в строке. Если у вас максимум 64 бита, почему бы просто не использовать switch для длины строки?

switch((strlen(bitStr) - 1) >> 3) {
  case 0: return 8;  /* strlen <= 8 */
  case 1: return 16; /* strlen <= 16 */
  case 2:
  case 3: return 32; /* strlen <= 32 */
  case 4:
  case 5:
  case 6:
  case 7: return 64; /* strlen <= 64 */
  default: return 0;
}

Кроме того, вы можете попробовать это:

int reqIntSz(char *bitStr)
{
  int len = strlen(bitStr);
  int res = 8;
  while ( len > res ) res <<= 1;
  return res;
}
0 голосов
/ 01 октября 2011

Вы хотите округлить длину в битах до степени два с минимумом 8. В Википедии есть приличный алгоритм для этого. Суть алгоритма состоит в том, чтобы установить каждый бит ниже самого высокогонемного, затем добавьте единицу.

Вам придется немного его откорректировать, поскольку вы не хотите округлять 8 до 16, но это достаточно просто, чтобы разобраться самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...