2012-06-06 18 views
49

A veces veo constantes de entero definidas en hexadecimal, en lugar de números decimales. Esta es una pequeña parte que tomé de una clase GL10:¿Por qué usar constantes hexadecimales?

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 obvio que es más simple de definir 2914 en lugar de 0x0B62, por lo que es allí quizá algunos ganancia de rendimiento? Literalmente no lo creo, desde entonces debería ser el trabajo del compilador cambiarlo.

+7

No hay nada de rendimiento al respecto - a veces es una convención de codificación, a veces es una máscara de bits, a veces es una variable de bandera, a veces es solo un número – Petesh

+3

Y a veces es sólo para confundir a los principiantes;) – mallaudin

+0

@mallaudin Los principiantes primero deben aprender los conceptos básicos. No OpenGl. –

Respuesta

56

Es probable para la limpieza organizativa 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 las anteriores, las constantes se agrupan con muchos dígitos en común.Si estuvieran representados en decimal, 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.

Además, en muchas situaciones, se desea poder combinar las constantes OR juntas para crear una combinación de banderas. Si el valor de cada constante está restringido para que solo tenga un subconjunto de los bits distinto de cero, esto puede hacerse de una manera que pueda volverse a separar. El uso de constantes hexadecimales deja en claro qué bits son distintos de cero en cada valor.

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

+1

Tiene toda la razón al combinar las constantes con O bit-bit ... O se olvidó por completo de eso ... –

9

Legibilidad al aplicar hexadecimal masks, por ejemplo.

2

No hay ganancia de rendimiento.

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

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

+0

No solo eso, sino que algunos lenguajes de programación no tienen un tipo de datos binarios, y como dijiste, convertir de binario a hexadecimal y viceversa es mucho más fácil en comparación con el decimal. 0001 == 1 0010 == 2 0011 == 3 ... 1001 == 9 1010 == A ... 1110 == E 1111 == F. Hay una relación de letra hexadecimal de 4 a 1. Entonces, A3 = 10100011 –

8

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

Las computadoras no hacen decimales, lo hacen (a lo sumo) binario. El hexadecimal se correlaciona con el binario de forma muy limpia, pero requiere un poco de trabajo convertir un número decimal en binario.

Un lugar donde brilla hexadecimal es cuando tiene una serie de elementos relacionados, donde muchos son similares, pero ligeramente diferentes.

// 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, uno sería difícil "tomar en cuenta" regiones constantes de bits a través de un gran número de diferentes, pero artículos relacionados.

+0

¿Por qué dices "ellos [las computadoras] lo hacen (en el mejor de los casos) binario"? ¿Alguna vez ha trabajado con una computadora que hizo algo más que binario? Tenía la impresión de que las computadoras que trabajaban con otras bases, como trinarias, eran en su mayoría simplemente hipotéticas, con algunas construidas como prueba de conceptos. – ArtOfWarfare

+0

El (en el mejor de los casos) estaba destinado a ser un indicador de que todas las operaciones subyacentes en las computadoras comunes son de naturaleza binaria y no están diseñadas intrínsecamente en las potencias superiores (trinario, octal, decimal, hexadecimal, etc.). He tenido que lidiar con tres lógica de estado, pero no una computadora completa construida sobre tres lógica de estado. Algunos de los circuitos de terminación de los interruptores en los sistemas de control tienen tres estados, "abierto/cerrado/averiado", donde el fallo indica que el circuito no puede confirmar que esté correctamente abierto o cerrado. Naturalmente, simplemente traducimos eso en dos bits binarios y asignamos un estado extra de "error". –

3

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

5

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

Además, a veces es significativo para las conversiones a binario: un número hexadecimal puede convertirse muy fácilmente en 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.

3

0xB62 es igual a 2914 :-)

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

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 indicadores individuales, por ejemplo) son relevantes.

22

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

No sé sobre ese caso en particular, pero muy a menudo que no es cierto.

Fuera de las dos preguntas:

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

B será respondido más correctamente más rápido por una gran cantidad de desarrolladores. (Esto va para preguntas similares, así)


0x0B62 (que es de 4 dígitos hexadecimales largo por lo que reprensents un número de 16 bits)

  • los bits de 0 = 0,000
  • los bits de B = 1,011
  • los bits de 6 = 0110
  • los bits de 2 = 0010

->

(Te reto a que hagan lo mismo con 2914.)


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

A veces me resulta tonto, como en:

public static final int NUMBER_OF_TIMES_TO_ASK_FOR_CONFIRMATION = ...; 

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

+0

El razonamiento sobre la conversión es bastante débil: Inicio - Programas - Estándar - Calculadora - ingrese número decimal - cambie al modo binario - ganancia !De hecho, tengo la Calculadora en la barra de tareas, así que omita los pasos 1-3. – Kromster

+5

Lamento que mi punto no fuera lo suficientemente claro. Los "cálculos" anteriores los hago de manera casi instantánea yo y otros: a menudo terminamos antes de pegar el valor en su calculadora. Muy a menudo me encuentro interesado solo en un bit (una bandera), así que no escaneo toda la cadena, solo encuentro el byte/dígito que cubre el bit en cuestión. – esej

+4

@esej: Para aclarar las cosas, compare la dificultad de encontrar el patrón de bits de 0x60000000 contra 1610612736. Si ambos números tienen muchos dígitos distintos de cero, la diferencia en dificultad no es tan clara, pero una Muchos de los valores hexadecimales prácticos consisten principalmente en ceros y F's. – supercat

6

¿Prefiere escribir 0xFFFFFFFF o 4294967295?

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

+0

0x es ideal para valores de color RGBA; en otros casos, las buenas constantes antiguas * GL_SOMETHING * son las mejores. – Kromster

1

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

Otras veces, es divertido o rompe la monotonía, aunque las personas no familiarizadas con hex puede pensar que usted está haciendo las cosas con punteros

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

veces lo uso para revisar los límites de cosas como enteros. Por ejemplo, puede usar 0x7FFFFFFF (0x80000000 funciona en muchos casos, pero 0x7F ... es más seguro) para obtener un máximo de límites int. Es útil para establecer una constante de error muy alta si no tiene un lenguaje que tenga algo como MAX_INT. La técnica también se escala, ya que para 64 bits, puede usar 0x7FFFFFFFFFFFFFFF. Puede observar que Android utiliza 0x7_ __ para búsquedas de tabla R.id.

Apuesto a que lo hacen por motivos de claridad. Puedes usar números enteros fácilmente, pero si estás familiarizado con el hexadecimal, no está mal. Parece que están reservando x valores para ciertas funciones. En decimal, haría algo como 0-99 es errores, 100-199 para otra cosa, y así sucesivamente. Cómo lo están haciendo es escalado de manera diferente.

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

3

Ahh pero 0xDECAFF es primo (1460959) y tiene un agradable color púrpura (en RGB).

Para colores hex es MUCHO más conveniente.

FF FF FF es blanco 00 00 FF es azul FF 00 00 es de color 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 tiende a tirar ¡todo está fuera, pero ignoraremos esos incómodos hechos físicos para una precisión matemática pura!

Cuestiones relacionadas