2017-02-21 1 views
0

У меня есть переменная size_tnOffset, которая содержит ряд из которых я хочу узнать, сколько байтов действительно необходимо для его хранения. Я полагаю, что положение MSB также может быть использовано? Это мой код до сих пор (sizeof(size_t) составляет 4):Как узнать, сколько байтов необходимо для хранения значения (int) в C

int nLen = 0; 
if (nOffset > 0xFFFFFF) 
{ 
    nLen = 4; 
} 
else if (nOffset > 0xFFFF) 
{ 
    nLen = 3; 
} 
else if (nOffset > 0xFF) 
{ 
    nLen = 2; 
} 
else 
{ 
    nLen = 1; 
} 
+0

Альтернативой, не обязательно намного лучше, является использование цикла для проверки того, есть ли все, кроме нижнего (наименее значимого) байта, любые ненулевые биты. –

+1

Лучше использовать формулу из теории информации вместо цикла: '(size_t) (log (number)/log (2))' – EgorBr

+0

Фактически код OP (который по существу является развернутым контуром) будет быстрее, чем цикл, который, в свою очередь, будет быстрее, чем вычисление логарифмов. –

ответ

1

Это гораздо проще использовать цикл и предопределенные константы.

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

Следующие выводит количество байт, необходимых для хранения точности целого числа:

size_t a = SIZE_MAX; 

size_t bytes = 0; 
while(a != 0) 
{ 
    a /= (1u << CHAR_BIT); 
    bytes++; 
} 
+0

Так как это значения без знака, вы можете заменить 'a/= (1u << CHAR_BIT);' с более простым 'a >> = CHAR_BIT;' в цикле. – user694733

+0

@ user694733 Первоначально код обрабатывал знаковые целые числа. – 2501

1

Вы можете использовать следующие функции встроены в GCC

- Встроенная функции: int __builtin_clz (unsigned int x)
Возвращает число ведущих 0-бит в X, начиная с самой значительной битовой позиции. Если X - 0, результат не определен.

- Встроенная функция: int __builtin_clzl (unsigned long)
Подобно __builtin_clz, за исключением типа аргумента unsigned long.

- Встроенная функция: int __builtin_clzll (unsigned long long)
Подобно __builtin_clz, за исключением типа аргумента unsigned long long.

После нахождения числа ведущих нулей, то простые расчеты (num_bits = число битов в int - ведущие нули), чтобы найти число битов, необходимых. Вы можете изменить количество байтов, необходимое с помощью (num_bits + 7)/8.

+1

[Пример кода] (http://ideone.com/H1f1o7). Вы можете добавить 'if (u == 0) return 1;' если 0 вход возможен. –

+0

'_BitScanReverse' может использоваться для аналогичной цели на MSVC – sp2danny

+0

OP не упоминает GCC, поэтому я бы предположил, что они хотят решения в стандартном C. – Lundin

1

Если вы ищете, сколько байт принимаются в int переменной, вы можете посмотреть в limits.h библиотеку, особенно INT_MIN и INT_MAX константы, то число байтов может быть рассчитана.

Если вы ищете, сколько байт необходимо для кодирования определенного целого, либо

  1. Используйте алгоритм, найти наименьшее мощность 2 pow(2, N) это равно или больше, чем число, N будет минимальное количество бит. Это просто, но имеет небольшой улов, когда целое число отрицательное, см. https://softwareengineering.stackexchange.com/questions/239036/how-are-negative-signed-values-stored.

  2. Или попробуйте распечатать бит номера и посчитать их, см. C printing bits.

0

Просто перебирайте данные, начиная с MSB, и замаскируйте каждый байт 0xFF. Чтобы узнать, какой байт является MSB портативным, вам нужно использовать бит-сдвиги.

В этом фрагменте i - это количество бит, которое нужно сдвинуть.

size_t i; 
for(i=sizeof(data)*8; i!=0; i-=8) 
{ 
    if((data >> (i-8)) & 0xFF) 
    { 
    break; 
    } 
} 

size_t bytes_to_copy = i/8; 
Смежные вопросы