Вопрос C: off_t (и другие целочисленные типы со знаком) минимальные и максимальные значения

Иногда я сталкиваюсь с целочисленным типом (например, целочисленный тип со знаком POSIX off_t ), где было бы полезно иметь макрос для его минимального и максимального значений , но я не знаю, как сделать такой действительно портативный.


Я всегда думал, что для целочисленных типов без знака это просто. 0 для минимума и ~ 0 для максимума. С тех пор я читал о нескольких различных потоках SO, которые предлагают использовать -1 вместо ~ 0 для переносимости. Здесь есть интересная тема с некоторыми спорами:
c ++ - безопасно ли использовать -1 для установки всех битов в истинное значение? - Stack Overflow

Однако даже после прочтения этой проблемы я все еще не понимаю. Кроме того, я ищу что-то совместимое с C89 и C99, поэтому я не знаю, применимы ли те же методы. Скажем, у меня был тип uint_whatever_t . Разве я не мог сначала просто привести к 0, а затем побитовое дополнение? Будет ли это нормально?:

#define UINT_WHATEVER_T_MAX ( ~ (uint_whatever_t) 0 )


Целочисленные типы со знаком выглядят так, как будто они будут более крепким орешком. Я видел несколько различных возможных решений, но только одно кажется переносимым. Либо так, либо это неправильно. Я нашел это во время поиска в Google для OFF_T_MAX и OFF_T_MIN. Кредит Кристиану Биеру:

#define MAX_INT_VAL_STEP(t) \
    ((t) 1 << (CHAR_BIT * sizeof(t) - 1 - ((t) -1 < 1))) 

#define MAX_INT_VAL(t) \
    ((MAX_INT_VAL_STEP(t) - 1) + MAX_INT_VAL_STEP(t))

#define MIN_INT_VAL(t) \
    ((t) -MAX_INT_VAL(t) - 1)

[...]
#define OFF_T_MAX MAX_INT_VAL(off_t) 


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

Это может означать, что можно использовать только три перечисленных представления числа со знаком. Правильно ли предположение, и совместимы ли макросы, указанные выше, со всеми тремя представлениями?


Другие мысли:
Кажется, что подобный функции макрос MAX_INT_VAL_STEP() дал бы неверный результат, если бы были биты заполнения. Интересно, есть ли способ обойти это?

При чтении представлений чисел со знаком в Википедии мне приходит в голову, что для всех трех представлений целых чисел со знаком MAX любого целочисленного типа со знаком MAX будет:
знаковый бит отключен, все биты значения включены (все три)
И его MIN будет либо:
бит знака включен, все биты значения включены (знак и величина)
знаковый бит включен, все биты значения отключены (добавление единиц / двоек)

Я думаю, что могу проверить знак и величину, сделав это:

#define OFF_T_MIN ( ( ( (off_t)1 | ( ~ (off_t) -1 ) ) != (off_t)1 ) ? /* sign and magnitude minimum value here */ : /* ones and twos complement minimum value here */ )

Тогда, поскольку знак и величина являются знаковыми битами, а все биты значений не будут минимум для off_t в этом случае будет ~ (off_t) 0 ? И для минимального дополнения один / два мне понадобится какой-то способ отключить все биты значения, но оставить бит знака включенным. Не знаю, как это сделать, не зная количества битов значения. Также гарантируется ли, что знаковый бит всегда будет на единицу более значимым, чем бит самого значимого значения?

Спасибо и дайте мне знать, если это слишком длинный пост



ИЗМЕНИТЬ 29.12.2010 17:00 EST :
Как ответил ниже ephemient, чтобы получить максимальное значение беззнакового типа, (беззнаковый тип) -1 более правильно, чем ~ 0 или даже ~ (беззнаковый тип) 0 . Из того, что я могу понять, когда вы используете -1, это то же самое, что и 0-1, что всегда будет приводить к максимальному значению в типе без знака.

Кроме того, поскольку максимальное значение типа без знака может быть определено, оно равно можно определить, сколько битов значения находится в беззнаковом типе. Благодарим Холлварда Б. Фурусета за его макрос, похожий на функцию IMAX_BITS (), который он опубликовал в ответ на вопрос на comp.lang.c

/* Number of bits in inttype_MAX, or in any (1<

IMAX_BITS (INT_MAX) вычисляет количество битов в int, а IMAX_BITS ((unsigned_type) -1) вычисляет количество бит в unsigned_type. Во всяком случае, пока кто-то не реализует 4-гигабайтные целые числа: -)

Однако суть моего вопроса остается без ответа: как определить минимальное и максимальное значения подписанного типа с помощью макроса. Я все еще занимаюсь этим. Возможно, ответ - нет.

Если вы не просматриваете этот вопрос в StackOverflow, в большинстве случаев вы не можете увидеть предложенные ответы, пока они не будут приняты. Предлагается просмотреть этот вопрос на StackOverflow .

11
задан Community 23 May 2017 в 11:45
поделиться