Получение max беззнакового целого с побитовым значением не по нулевому значению

Я пытаюсь получить максимальное значение некоторого целого целого без знака без включения каких-либо заголовков типа <limits>. Поэтому я подумал, что просто перевернул биты значения без знака 0.

#include <iostream>
#include <limits>

int main()
{
    std::cout << (~0U) << '\n'; // #1
    std::cout << (std::numeric_limits< unsigned >::max()) << '\n'; // #2
    return 0;
}

Я не очень разбираюсь в тонких различиях между ними. Вот почему я спрашиваю, может ли возникнуть какое-то неожиданное поведение или проблемы с платформой/архитектурой, используя первый метод.

Ответ 1

... для получения максимального значения определенного целого беззнакового типа без включения заголовков

Просто присвойте значение -1

unsigned_type_of_choice max = -1;

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

Ниже не указано максимальное значение типа назначения. Он не работает, когда диапазон типа назначения превышает диапазон unsigned, который является типом ~0U. @Кристофер Ойклс

// problem
unsigned_type_of_choice max_wannabe = ~0U;

Ответ 2

Нельзя назначать ~0U только любому неподписанному типу, chux answer уже объясняет, почему.

Для С++ со следующим вы можете получить максимально возможное значение для всех неподписанных типов.

template <typename T>
T max_for_unsigned_type() {
    return ~(static_cast<T> (0));
}

Вы отрицаете нуль вашего точного типа. Я использую подробное имя функции, потому что оно не должно использоваться для подписанных значений. Проблема в том, что для проверки подписности самым простым способом будет включение дополнительного заголовка, а именно type_traits. Этот другой ответ был бы полезен.

Использование:

max_for_unsigned_type<uint8_t> ();
max_for_unsigned_type<uint16_t> ();
max_for_unsigned_type<uint32_t> ();
max_for_unsigned_type<uint64_t> ();
max_for_unsigned_type<unsigned> ();

Возвращенные значения: (см. тестовый код здесь)

255
65535
4294967295
18446744073709551615
4294967295

Примечание. Выполнение этого для подписанных типов намного сложнее, см. Программное определение максимального значения целочисленного типа со знаком.