2014-01-08 8 views
1

Скажем, есть тип данных, определенный как таковой:Препроцессор C определяет для значения заданного типа, где каждый байт равен 0xFF?

typedef int my_integer_type; 

Где-то еще, существует подобный код

#define MAX_MY_INTEGER_TYPE 0xFFFFFFFF 

Однако, если my_integer_type позже изменено на 8 байт вместо 4, MAX_MY_INTEGER_TYPE будет необходимо также обновить. Есть ли способ для MAX_MY_INTEGER_TYPE быть более умным, чтобы в основном представлять количество байтов в my_integer_type, все установлены в 0xFF?

Я понимаю, что существуют другие традиционные способы получения максимального целочисленного размера (например, здесь: maximum value of int), но мой фактический прецедент немного сложнее, и я не могу применять эти решения.

+5

Это кажется максимальным для ** неподписанного типа **. Если это так, то просто '#define MAX_MY_INTEGER ((my_unsigned_integer) -1)'. –

+0

@ H2CO3 - Вы имели в виду '#define MAX_MY_INTEGER_TYPE ((my_integer_type) 0 - 1)'? EDIT: Nevermind, я вижу, вы выбрасывали -1. Уже пятница? –

+0

Если вы хотите установить все биты в 1 в неподписанном типе, вы можете использовать '#define MAX_MY_INTEGER_TYPE -1' Я не уверен, что гарантии для подписанных типов, хотя я подозреваю, что он также установил бы все биты в 1 на системах комплемента 2. – nos

ответ

-2

Вы можете использовать предопределенные типы из заголовка stdint.h.

typedef int32_t my_integer_type; 

И вы уверены, что ваш тип будет иметь 4 байта на всех платформах.

+2

Это не то, что OP хочет выполнить – Olotiar

+0

Причина, по которой я не могу это сделать, заключается в том, что typedef не под моим контролем - он предоставляется как часть библиотеки от третьей стороны, и я никак не могу ее контролировать. –

+0

Может быть. Но #define MAX_MY_INTEGER_TYPE 0xFFFFFFFF не является действительно максимальным значением типа int. 0xFFFFFFFF = -1 (http://en.wikipedia.org/wiki/Two%27s_complement). Я всегда использую типы stdint, чтобы избежать неприятных ошибок. Некото ответил: '#define MAX_MY_INTEGER_TYPE (my_integer_type) (- 1)' – pal23

1

Вы можете вычислить максимальный размер целого числа, например, используя битовые операции.

Для целого числа без знака вы можете сделать это следующим образом:

const unsigned int MAX_SIZE = ~0; 

или, вы можете сделать это так, если ваш компилятор не жалуется:

const unsigned int MAX_SIZE = -1; 

EDIT

Для вашего конкретного случая кажется, что вы хотите иметь возможность вычислить максимальное значение подписанного типа. Предполагая, что знак вычисляется с использованием 2 в дополнение (как в большинстве систем), вы можете использовать эти методы:

const my_integer_type MAX_MY_INTEGER_TYPE = 
    ~((my_integer_type)1 << (sizeof(my_integer_type) * CHAR_BIT) - 1); 

Итак, что я здесь вычислить размер типа. Независимо от размера, я собираюсь вычесть 1 из этого. Я использую результирующее число, чтобы сдвинуть позицию 1 влево влево. Затем я инвертирую все это.

Предположим, что my_integer_type - 1 байт. Это 8 бит, что означает, что сумма сдвига равна 7. Я беру 1 и сдвигаю его. Результат сдвига выглядит так: 0x80. Когда вы инвертируете его, вы получите следующее: 0x7f. И это максимальное значение (конечно, если предположить, что он использует дополнение 2).

Обратите внимание, что я не использовал препроцессор. К сожалению, preprossor - простой инструмент поиска и замены, который не знает типов в C. Таким образом, вам придется использовать константы.

+0

'(unsigned) (~ 0) >> 1' не работает для того, что запросит OP. '~ 0' является' int', и вы передаете его 'unsigned', но OP нуждается в настраиваемом типе. Вы можете начать с '~ (my_integer_type) 0', чтобы получить все в типе OP, но тогда у вас нет неподписанного типа для его включения, поэтому вы не можете безопасно смещать бит. –

+0

Вы были правы. Но я думаю, что теперь я это исправил. Дайте мне знать, если это сработает для вас. – Marcos

+0

Это не работает во всех случаях, разрешенных стандартом C. Целочисленные типы могут иметь биты заполнения, а смещение влево знака целого типа в знаковый бит делает поведение неопределенным. (И также вы не должны использовать '8' как константу, но' CHAR_BIT') –

0

Непонятно, что OP хочет «каждый байт равен 0xFF» или максимальное целочисленное значение.

1) [Изменить] Предполагая, что «каждый байт 0xFF» является целью OP, в @Eric Postpischil идея звук и простой

// Better name: MY_INTEGER_TYPE_ALL_BITS_SET 
#define MAX_MY_INTEGER_TYPE (~ (my_integer_type) 0) 

2) Интересно ОП просит «значение данного типа, где каждый байт равен 0xFF? " и затем переходит к вызову «MAX_MY_INTEGER_TYPE».Это делает звук как unsigned как максимум signed Значение редко (если когда-либо) «каждый байт равен 0xFF». Использование -1, как предложено @ H2CO3, выглядит неплохо.

#define MAX_MY_INTEGER ((my_integer_type) 0 - 1). 

3) Пока не ответили: если OP хочет максимальное значение и my_integer_typeможет быть подписан (и не предполагая 2 в дополнение).

1

Нет, для знаковых целых типов в принципе нет возможности рассчитать максимальные значения для типа. Это основная причина, почему существуют все предопределенные MAX -макросы, такие как INT_MAX. Чтобы избежать этой проблемы обслуживания вы могли бы пойти в другую сторону круглый

#include <limits.h> 

#define MY_INTEGER_TYPE_MAX 0xFFFF...FFF // whatever number of 'F' you chose 

#if MY_INTEGER_TYPE_MAX <= SCHAR_MAX 
typedef signed char my_integer_type; 
#elsif MY_INTEGER_TYPE_MAX <= SHRT_MAX 
typedef signed short int my_integer_type; 
#elsif MY_INTEGER_TYPE_MAX <= INT_MAX 
typedef signed int my_integer_type; 
#elsif MY_INTEGER_TYPE_MAX <= LONG_MAX 
typedef signed long int my_integer_type; 
#elsif MY_INTEGER_TYPE_MAX <= LLONG_MAX 
typedef signed long long int my_integer_type; 
#else 
typedef intmax_t my_integer_type; 
#endif 

Вы видите, что это не очень длинный список дел, которые вы должны различать.

+0

Вы должны посмотреть на мой ответ. Я рассчитываю максимальное значение для подписанного числа. – Marcos

+1

@Marcos, вы должны посмотреть на стандарт C :) В вашем ответе вы делаете предположения о знаковых целых числах, которые не выполняются на всех платформах. В частности, вы предполагаете, что тип не имеет битов заполнения, а ваш сдвиг влево имеет неопределенное поведение. –

Смежные вопросы