¿Por qué usar constantes hexadecimales?


A veces veo constantes enteras definidas en hexadecimal, en lugar de números decimales. Esta es una pequeña parte que tomé de una clase GL10:

public static final int GL_STACK_UNDERFLOW = 0x0504;
public static final int GL_OUT_OF_MEMORY = 0x0505;
public static final int GL_EXP = 0x0800;
public static final int GL_EXP2 = 0x0801;
public static final int GL_FOG_DENSITY = 0x0B62;
public static final int GL_FOG_START = 0x0B63;
public static final int GL_FOG_END = 0x0B64;
public static final int GL_FOG_MODE = 0x0B65;

Es obviamente más simple definir 2914 en lugar de 0x0B62, así que ¿hay tal vez alguna ganancia de rendimiento? Realmente no lo creo, ya que debería ser el trabajo del compilador cambiarlo.

Author: Christopher Orr, 2012-06-06

11 answers

Es probable que para la limpieza organizacional y visual. La base 16 tiene una relación mucho más simple con el binario que la base 10, porque en la base 16 cada dígito corresponde exactamente a cuatro bits.

Observe cómo en lo anterior, las constantes se agrupan con muchos dígitos en común. Si se representaran en decimales, los bits en común serían menos claros. Si en cambio tuvieran dígitos decimales en común, los patrones de bits no tendrían el mismo grado de similitud.

También, en muchos situaciones se desea ser capaz de bitwise-O constantes juntos para crear una combinación de banderas. Si el valor de cada constante se limita a tener solo un subconjunto de los bits distintos de cero, entonces esto se puede hacer de una manera que se puede volver a separar. El uso de constantes hexadecimales deja claro qué bits son distintos de cero en cada valor.

Hay otras dos posibilidades razonables: octal, o base 8 simplemente codifica 3 bits por dígito. Y luego hay decimal codificado binario, en el que cada dígito requiere cuatro bits, pero los valores de dígitos por encima de 9 están prohibidos - eso sería desventajoso, ya que no puede representar todas las posibilidades que binario puede.

 60
Author: Chris Stratton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 19:07:41

"Obviamente es más simple definir 2914 en lugar de 0x0B62"

No conozco ese caso específico, pero muy a menudo eso no es cierto.

De las dos preguntas:

  • A) ¿Cuál es el valor de bit de 2914?
  • B) ¿Cuál es el valor de bit de 0x0B62?

B será contestado más correctamente más rápido por muchos desarrolladores. (Esto va para preguntas similares también)


0x0B62 (tiene 4 dígitos hexadecimales de largo, por lo que reprensenta un 16-bit número)

  • los bits de 0 = 0000
  • los bits de B = 1011
  • los bits de 6 = 0110
  • los bits de 2 = 0010

->

0000101101100010

(Te reto a hacer lo mismo con 2914.)


Esa es una razón para usar el valor hexadecimal, otra es que la fuente del valor podría usar hexadecimal (el estándar de una especificación, por ejemplo).

A veces me parece tonto, como en:

public static final int NUMBER_OF_TIMES_TO_ASK_FOR_CONFIRMATION = ...;

Casi siempre sería tonto para escribir en hexadecimal, estoy seguro de que hay algunos casos en los que no lo haría.

 24
Author: esej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 20:41:07

Legibilidad al aplicar máscaras hexadecimales , por ejemplo.

 9
Author: Alexis Pigeon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 19:03:15

No habrá ganancia de rendimiento entre un número decimal y un número hexadecimal, porque el código se compilará para mover constantes de bytes que representan números.

Las computadoras no hacen decimales, hacen (en el mejor de los casos) binarios. Mapas hexadecimales a binario muy limpiamente, pero requiere un poco de trabajo para convertir un número decimal a binario.

Un lugar donde brilla hexadecimal es cuando tienes un número de elementos relacionados, donde muchos son similares, pero ligeramente diferente.

// These error flags tend to indicate that error flags probably
// all start with 0x05..
public static final int GL_STACK_UNDERFLOW = 0x0504;
public static final int GL_OUT_OF_MEMORY = 0x0505;

// These EXP flags tend to indicate that EXP flags probably
// all start with 0x08..
public static final int GL_EXP = 0x0800;
public static final int GL_EXP2 = 0x0801;

// These FOG flags tend to indicate that FOG flags probably
// all start with 0x0B.., or maybe 0x0B^.
public static final int GL_FOG_DENSITY = 0x0B62;
public static final int GL_FOG_START = 0x0B63;
public static final int GL_FOG_END = 0x0B64;
public static final int GL_FOG_MODE = 0x0B65;

Con números decimales, sería difícil "notar" regiones constantes de bits a través de un gran número de elementos diferentes, pero relacionados.

 8
Author: Edwin Buck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 19:58:48

¿Preferirías escribir 0xFFFFFFFF o 4294967295?

El primero representa mucho más claramente un tipo de datos de 32 bits con todos. Por supuesto, muchos programadores experimentados reconocerían este último patrón, y tendrían una sospecha furtiva en cuanto a su verdadero significado. Sin embargo, incluso en ese caso, es mucho más propenso a errores de escritura, etc.

 6
Author: tskuzzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 19:59:33

Cuando se trata de números grandes, representarlos en hexadecimal los hace más legibles, porque son más compactos.

También, a veces es significativo para las conversiones a binario: un número hexadecimal puede ser muy fácil convertido a binario. A algunos programadores les gusta hacer esto, ayuda al hacer operaciones de bits en los números.

En cuanto a la ganancia de rendimiento: no, no hay ninguna.

 5
Author: Radu Murzea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 19:04:44

Hexadecimal es el formato legible más cercano al formato binario. Esto simplifica mucho las operaciones de bits por ejemplo

 3
Author: GETah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 19:04:25

0xB62 es igual a 2914: -)

Para los desarrolladores es mucho más fácil imaginar mentalmente el patrón de bits de una constante cuando se presenta en hexadecimal que cuando se presenta como un entero base 10.

Este hecho hace que la presentación en hexadecimal sea más adecuada para las constantes utilizadas en las API donde los bits y sus posiciones (utilizados como banderas individuales, por ejemplo) son relevantes.

 3
Author: rsp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 19:05:28

Ahh pero 0xDECAFF es a la vez primo (1460959), y un agradable color púrpura (en RGB).

Para los colores hex es mucho más conveniente.

FF FF FF es blanco 00 00 FF es azul FF 00 00 es rojo 00 FF 00 es verde Es fácil ver las relaciones de color como números (aunque la gamma y la fidelidad del ojo humano tienden a despistar las cosas, ¡pero ignoraremos esos hechos físicos inconvenientes para una precisión matemática pura!

 3
Author: ggb667,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-18 15:16:09

No hay ganancia de rendimiento.

Sin embargo, si estas constantes corresponden a ciertos bits debajo, la mayoría de los programadores prefieren Hex (o incluso binario) para hacerlo claro y más legible.

Por ejemplo, se puede ver fácilmente que GL_EXP2 tiene 2 bits, el 1 bit y el 0x0800 bit (que es 2048 decimal). Un valor decimal de 2049 sería menos claro.

 2
Author: user949300,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 19:03:55

A veces es más fácil usar algoritmos relacionados con bits. Otras veces, se trata de comparaciones de bits, como mi declaración en un comentario, 4 bits (dígitos binarios) convertir a 1 letra hexadecimal, por lo tanto, A3 = 10100011.

Otras veces, es divertido o rompe la monotonía, aunque la gente que no está familiarizada con hex puede pensar que estás haciendo cosas con punteros

int data = 0xF00D;
if ( val != 0xC0FFEE )
{
   data = 0xDECAF;
}

A veces lo uso para comprobar los límites de cosas como ints. Por ejemplo, puede usar 0x7FFFFFFF (0x80000000 funciona en muchos casos, pero el 0x7F... es más seguro) para obtener un máximo int límites. Es útil para establecer una constante de error muy alta si no tienes un idioma que tenga algo como MAX_INT. La técnica también se escala, ya que para 64 bits, puede usar 0x7FFFFFFFFFFFFFFF. Usted puede notar que Android utiliza 0x7___ para R.id consulta de mesas.

Apuesto a que lo están haciendo por el bien de la claridad. Puede usar enteros fácilmente, pero si está familiarizado con hex, no está mal. Parece que están reservando valores de x para ciertas funciones. En decimal, haría algo como 0-99 es errores, 100-199 para otra cosa, y así sucesivamente. La forma en que lo están haciendo se escala de manera diferente.

En cuanto al rendimiento, no se obtiene nada en tiempo de ejecución ya que el compilador (incluso muchos ensambladores) convierte cualquier formato a binario al final, ya sea decimal, octal, hexadecimal, flotante, doble, etc.

 1
Author: Joe Plante,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-03 15:13:41