Существует функционально-подобный макрос, который может определять биты значения **** целочисленного типа ****, но только если вы уже знаете максимальное значение этого типа.Получите ли вы постоянную времени компиляции или нет, зависит от вашего компилятора, но я думаю, что в большинстве случаев ответ будет положительным.
Благодарность Холлварду Б. Фурусету за его функциональный макрос IMAX_BITS (), которыйон отправил в ответ на вопрос на comp.lang.c
/* Number of bits in inttype_MAX, or in any (1<<b)-1 where 0 <= b < 3E+10 */
#define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) /0x3fffffffL %0x3fffffffL *30 \
+ (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4-12/((m)%31+3))
IMAX_BITS (INT_MAX) вычисляет количество бит в int, а IMAX_BITS ((unsigned_type)-1) вычисляет количество битов в unsigned_type.Пока кто-нибудь не реализует 4-гигабайтные целые числа, так или иначе: -)
и кредит Эрику Сосману за эту альтернативную версию , которая должна работать с меньшими затратамичем 2040 битов:
(РЕДАКТИРОВАНИЕ 1/3/2011 23:30 EST: Оказывается, эта версия была также написана Халлвардом Б. Фурусетом)
/* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */
#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))
Помните, что, хотя ширина целого типа без знака равна количеству битов значения, ширина целочисленного типа со знаком еще больше (§6.2.6.2 / 6). Это имеет особое значениеКак и в моем исходном комментарии к вашему вопросу, я неправильно указал, что макрос IMAX_BITS () вычисляет ширину, когда он фактически вычисляет количество битов значения.Извини за это!
Так, например, IMAX_BITS(INT64_MAX)
создаст постоянную времени компиляции 63. Однако в этом примере мы имеем дело с типом со знаком, поэтому вы должны добавить 1 для учета бит знака, если вы хотите фактическую ширинуint64_t, который, конечно, 64.
В отдельном обсуждении comp.lang.c пользователь с именем blargg дает описание того, как работает макрос:
Re: использование препроцессорадля подсчета битов в целочисленных типах ...
Обратите внимание, что макрос работает только с 2 ^ n-1 значениями (т.е. со всеми 1 в двоичном виде), как и следовало ожидать с любым значением MAX.Также обратите внимание, что хотя легко получить постоянную времени компиляции для максимального значения целого типа без знака (IMAX_BITS((unsigned type)-1)
), на момент написания этой статьи я не знаю, как сделать то же самое для подписанногоцелочисленный тип без вызова реализации, определенного поведения.Если я когда-нибудь узнаю, я отвечу на свой собственный вопрос SO, здесь:
C вопрос: минимальные и максимальные значения off_t (и другие целочисленные типы со знаком) - переполнение стека