static_cast español dynamic_cast c++ bit-manipulation idiomatic

dynamic_cast - static_cast c++ español



¿Static_cast<T>(-1) es la forma correcta de generar datos de todo-uno-bits sin numeric_limits? (5)

Estoy escribiendo código C ++ en un entorno en el que no tengo acceso a la biblioteca estándar de C ++, específicamente no a std::numeric_limits . Supongamos que quiero implementar

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

Centrándome en tipos integrales sin firmar, ¿qué coloco allí? Específicamente, ¿ static_cast<T>(-1) es suficientemente bueno? (Otros tipos que podría tratar como una matriz de caracteres sin firmar según su tamaño, supongo).


Centrándome en tipos integrales sin firmar, ¿qué coloco allí? Específicamente, es static_cast (-1) suficientemente bueno

Sí, es lo suficientemente bueno.

Pero prefiero un valor hexadecimal porque mi fondo es sistemas incrustados, y siempre he tenido que saber el tamaño de (T).

Incluso en sistemas de escritorio, conocemos los tamaños de la siguiente T:

uint8_t allones8 = 0xff; uint16_t allones16 = 0xffff; uint32_t allones32 = 0xffffffff; uint64_t allones64 = 0xffffffffffffffff;


Centrándome en tipos integrales sin firmar, ¿qué coloco allí? Específicamente, es static_cast (-1) suficientemente bueno

Si solo le preocupan los tipos sin firma, sí, convertir -1 es correcto para todas las implementaciones estándar de C ++. Se garantiza que las operaciones en tipos sin firmar, incluidas las conversiones de tipos con signo a tipos sin signo, funcionarán en módulo (máx + 1).


Esta manera desarmantemente directa.

T allOnes; memset(&allOnes, ~0, sizeof(T));


Use el operador bitwise NOT ~ en 0 .

T allOnes = ~(T)0;

Un static_cast<T>(-1) asume el complemento de dos, que no es portátil. Si solo le preocupan los tipos sin firma, la respuesta de hvd es el camino a seguir.

Ejemplo de trabajo: https://ideone.com/iV28u0


static_cast<T>(-1ull)

sería más correcto y funciona en cualquier formato firmado, independientemente del complemento de 1, el complemento de 2 o la magnitud del signo.

Porque el menos unario de un valor sin signo se define como

El negativo de una cantidad sin firmar se calcula restando su valor de 2 ^ n, donde n es el número de bits en el operando promovido ".

Por -1u tanto, -1u siempre devolverá datos de todos los bits en unsigned int . ll sufijo ll es para que funcione para cualquier tipo más estrecho que unsigned long long . No hay tipos de enteros extendidos (todavía) en C ++, así que esto debería estar bien

Sin embargo, una solución más adecuada sería

static_cast<T>(~0ull)