Вам нужно эффективно рассчитать log2 (i). Не существует тривиального способа сделать это мобильно, быстро, для максимального целочисленного значения, поддерживаемого компилятором и с помощью макроса.
Опции:
1.Рассчитайте логарифм в цикле:
// 64+-bit version:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long bits = 0;
while (i)
{
i >>= 1;
bits++;
}
if (bits == 0) bits = 1;
return (bits + 7) / 8; // we're assuming that byte=8 bits, but CHAR_BIT may be > 8
}
2.Используйте встроенную функцию (фактически выделенную инструкцию ЦП) компилятора, если она доступна. Для MSVC ++:
// 64-bit version, not available for 32-bit code:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long index;
if (_BitScanReverse64(&index, i) == 0)
{
index = 1;
}
return (index + 8) / 8;
}
// 32-bit version, available for 32 and 64-bit code:
unsigned long BYTES_REQUIRED(unsigned long i)
{
unsigned long index;
if (_BitScanReverse(&index, i) == 0)
{
index = 1;
}
return (index + 8) / 8;
}
// 64-bit version available for 32 and 64-bit code:
unsigned long BYTES_REQUIRED(unsigned long long i)
{
unsigned long index;
if (_BitScanReverse(&index, (unsigned long)(i >> 32)))
{
index += 32;
}
else if (_BitScanReverse(&index, (unsigned long)i) == 0)
{
index = 1;
}
return (index + 8) / 8;
}
3.Используйте if
или ?:
, зная размер самого большого поддерживаемого целочисленного типа ... Другие уже описали этот метод.