Как узнать ширину uint_fast32_t - PullRequest
2 голосов
/ 29 мая 2020

Я хотел бы иметь возможность переносить fprintf() a uint_fast32_t, как определено в stdint.h, со всеми ведущими нулями. Например, если моя платформа определила uint_fast32_t как 64-битное целое число без знака, я бы хотел fprintf() со спецификатором формата, например %016lX, но если это 32-битное целое число без знака, я бы хотел использовать %08lX.

Есть ли где-нибудь макрос типа INTFAST32_BITS, который я мог бы использовать?

прямо сейчас я использую

#if UINT_FAST32_MAX == 0xFFFFFFFF
#    define FORMAT "08"PRIXFAST32
#elif UINT_FAST32_MAX == 0xFFFFFFFFFFFFFFFF
#    define FORMAT "016"PRIXFAST32
#endif

Но это работает только с uint_fast32_t это ровно 32 или 64 бита, и код также немного неуклюжий и трудный для чтения

1 Ответ

4 голосов
/ 29 мая 2020

Вы можете найти размер uint_fast32_t так же, как вы можете найти размер любого другого типа: применив к нему оператор sizeof. Единицей результата является размер типа char. Пример:

size_t chars_in_a_uint_fast32_t = sizeof(uint_fast32_t);

Но этого недостаточно для печати одного с одной из функций printf -семейства. Неопределенное поведение возникает в printf et. al. , если какая-либо директива форматирования не соответствует типу соответствующего аргумента, а размер uint_fast32_t не является достаточной информацией для правильного сопоставления.

Здесь уже макросы форматирования описанный в , ваш второй ответ входит. Они предоставляют соответствующий модификатор размера и букву преобразования для каждого типа и преобразования. Для преобразования X в uint_fast32_t соответствующий макрос - PRIXFAST32.

Вы предоставляете любые флаги, ширину поля и точность как обычно. Если вы действительно хотите использовать ширину поля, адаптированную к фактическому размеру uint_fast32_t, то разумный способ сделать это - воспользоваться возможностью указать, что ширина поля передается в качестве аргумента (типа int). Таким образом:

uint_fast32_t fast;
// ...
printf("%0*" PRIXFAST32 "\n", (int) sizeof(fast) * 2, fast);

Однако я отмечаю, что это кажется немного сомнительным, поскольку вы делаете положение для значений шире, чем обычно, вы должны позволять становиться любому значению этого типа. Функция printf ни в коем случае не будет печатать меньше цифр, чем требуется для express значения, предполагая, что оно действительно имеет указанный тип, поэтому я был бы склонен просто использовать фиксированную ширину поля, достаточную для 32-битного целые числа (скажем, 8).

...