Подтвердить что ты не робот

Является ли static_cast <T> (- 1) правильным способом генерации данных с одним битом без numeric_limits?

Я пишу код С++ в среде, в которой у меня нет доступа к стандартной библиотеке С++, а именно к std::numeric_limits. Предположим, что я хочу реализовать

template <typename T> constexpr T all_ones( /* ... */ )

Фокусировка на неподписанных типах интегралов, что мне там положить? В частности, достаточно static_cast<T>(-1)? (Другие типы, которые я мог бы рассматривать как массив неподписанных символов на основе их размера, я думаю.)

4b9b3361

Ответ 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)