Является ли static_cast <T> (- 1) правильным способом генерации данных с одним битом без numeric_limits?
Я пишу код С++ в среде, в которой у меня нет доступа к стандартной библиотеке С++, а именно к std::numeric_limits
. Предположим, что я хочу реализовать
template <typename T> constexpr T all_ones( /* ... */ )
Фокусировка на неподписанных типах интегралов, что мне там положить? В частности, достаточно static_cast<T>(-1)
? (Другие типы, которые я мог бы рассматривать как массив неподписанных символов на основе их размера, я думаю.)
Ответы
Ответ 1
Используйте оператор bitwise NOT
~
на 0
.
T allOnes = ~(T)0;
A static_cast<T>(-1)
предполагает два дополнения, которые не переносимы. Если вас беспокоят только неподписанные типы, hvd answer - это путь.
Рабочий пример: https://ideone.com/iV28u0
Ответ 2
Фокусировка на неподписанных типах интегралов, что мне там положить? В частности, достаточно хорош static_cast (-1)
Если вас беспокоит только неподписанные типы, да, преобразование -1
корректно для всех стандартных реализаций С++. Гарантируется, что операции с неподписанными типами, включая преобразования подписанных типов в неподписанные типы, будут работать по модулю (max + 1).
Ответ 3
Этот безответственный прямой путь.
T allOnes;
memset(&allOnes, ~0, sizeof(T));
Ответ 4
Фокусировка на неподписанных типах интегралов, что мне там положить? В частности, достаточно хорош static_cast (-1)
Да, это достаточно хорошо.
Но я предпочитаю шестнадцатеричное значение, потому что мой фон - это встроенные системы, и мне всегда приходилось знать sizeof (T).
Даже в настольных системах мы знаем размеры следующих T:
uint8_t allones8 = 0xff;
uint16_t allones16 = 0xffff;
uint32_t allones32 = 0xffffffff;
uint64_t allones64 = 0xffffffffffffffff;
Ответ 5
Другой способ
static_cast<T>(-1ull)
который был бы более правильным и работал бы в любом целочисленном формате со знаком, независимо от 1 дополнения, 2 дополнения или величины знака. Вы также можете использовать static_cast<T>(-UINTMAX_C(1))
Потому что унарный минус беззнакового значения определяется как
Отрицательное значение беззнаковой величины вычисляется путем вычитания ее значения из 2 ^ n, где n - число битов в повышенном операнде. "
Поэтому -1u
всегда будет возвращать все -1u
данные в unsigned int
. Суффикс ll
предназначен для того, чтобы он работал для любых типов, более unsigned long long
чем unsigned long long
. В C++ нет расширенных целочисленных типов (пока)
Однако решение, которое выражает намерение более ясное, будет
static_cast<T>(~0ull)