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)