web-dev-qa-db-fra.com

Pourquoi utiliser des constantes hexadécimales?

Parfois, je vois des constantes entières définies en hexadécimal, au lieu de nombres décimaux. Voici une petite partie que j'ai prise dans un cours 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;

Il est évidemment plus simple de définir 2914 au lieu de 0x0B62, y a-t-il donc un gain de performances? Je ne pense pas vraiment, car alors ce devrait être le travail du compilateur de le changer.

53
user717572

C'est probablement pour la propreté organisationnelle et visuelle. La base 16 a une relation binaire beaucoup plus simple que la base 10, car dans la base 16, chaque chiffre correspond exactement à quatre bits.

Remarquez comment dans ce qui précède, les constantes sont regroupées avec de nombreux chiffres en commun. S'ils étaient représentés en décimal, les bits communs seraient moins clairs. S'ils avaient à la place des chiffres décimaux en commun, les motifs binaires n'auraient pas le même degré de similitude.

De plus, dans de nombreuses situations, il est souhaitable de pouvoir combiner les constantes OR au niveau du bit pour créer une combinaison d'indicateurs. Si la valeur de chaque constante est contrainte de n'avoir qu'un sous-ensemble de bits non nul, alors cela peut être fait d'une manière qui peut être re-séparée. L'utilisation de constantes hexadécimales indique clairement quels bits sont différents de zéro dans chaque valeur.

Il existe deux autres possibilités raisonnables: octal ou base 8 code simplement 3 bits par chiffre. Et puis il y a la décimale codée binaire, dans laquelle chaque chiffre nécessite quatre bits, mais les valeurs supérieures à 9 sont interdites - ce serait désavantageux car il ne peut pas représenter toutes les possibilités que le binaire peut.

62
Chris Stratton

"Il est évidemment plus simple de définir 2914 au lieu de 0x0B62"

Je ne connais pas ce cas spécifique, mais bien souvent ce n'est pas vrai.

Sur les deux questions:

  • A) Quelle est la valeur en bits de 2914?
  • B) Quelle est la valeur en bits de 0x0B62?

B sera répondu plus correctement plus rapidement par de nombreux développeurs. (Cela vaut également pour les questions similaires)


0x0B62 (c'est 4 chiffres hexadécimaux donc il représente un nombre de 16 bits)

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

->

0000101101100010

(Je vous mets au défi de faire de même avec 2914.)


C'est une raison pour utiliser la valeur hexadécimale, une autre est que la source de la valeur peut utiliser hexadécimal (la norme d'une spécification par exemple).

Parfois, je trouve ça idiot, comme dans:

public static final int NUMBER_OF_TIMES_TO_ASK_FOR_CONFIRMATION = ...;

Serait presque toujours idiot d'écrire en hexadécimal, je suis sûr qu'il y a des cas où cela ne le serait pas.

26
esej

Lisibilité lors de l'application hexadécimal masques , par exemple.

9
Alexis Pigeon

Il n'y aura aucun gain de performances entre un nombre décimal et un nombre hexadécimal, car le code sera compilé pour déplacer les constantes d'octets qui représentent des nombres.

Les ordinateurs ne font pas de décimales, ils font (au mieux) des binaires. Hexadécimal mappe très proprement au binaire, mais il faut un peu de travail pour convertir un nombre décimal en binaire.

Un endroit où l'hexadécimal brille est lorsque vous avez un certain nombre d'éléments liés, où beaucoup sont similaires, mais légèrement différents.

// 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;

Avec des nombres décimaux, on aurait du mal à "remarquer" des régions constantes de bits sur un grand nombre d'éléments différents mais liés.

8
Edwin Buck

Souhaitez-vous plutôt écrire 0xFFFFFFFF ou 4294967295?

Le premier représente beaucoup plus clairement un type de données 32 bits avec tous ceux-là. Bien sûr, de nombreux programmeurs chevronnés reconnaîtraient ce dernier modèle et soupçonneraient sa vraie signification. Cependant, même dans ce cas, il est beaucoup plus sujet aux erreurs de frappe, etc.

6
tskuzzy

En ce qui concerne les grands nombres, les représenter en hexadécimal les rend plus lisibles, car ils sont plus compacts.

De plus, il est parfois important pour les conversions en binaire: un nombre hexadécimal peut être très facilement converti en binaire. Certains programmeurs aiment le faire, cela aide lors des opérations de bits sur les nombres.

Quant au gain de performance: non, il n'y en a pas.

5
Radu Murzea

Hexadécimal est le format lisible le plus proche du format binaire. Cela simplifie par exemple beaucoup d'opérations sur les bits

3
GETah

0xB62 est égal à 2914 :-)

Pour les développeurs, il est beaucoup plus facile d'imaginer mentalement le motif binaire d'une constante lorsqu'il est présenté en hexadécimal que lorsqu'il est présenté comme un entier de base 10.

Ce fait rend la présentation en hexadécimal plus adaptée aux constantes utilisées dans les API où les bits et leurs positions (utilisés comme drapeaux individuels par exemple) sont pertinents.

3
rsp

Ahh mais 0xDECAFF est à la fois premier (1460959) et une couleur pourpre agréable (en RVB).

Pour les couleurs hexadécimales, c'est beaucoup plus pratique.

FF FF FF est blanc 00 00 FF est bleu FF 00 00 est rouge 00 FF 00 est vert Il est facile de voir les relations de couleur comme des nombres (bien que le gamma et la fidélité de l'œil humain aient tendance à gâcher les choses, mais nous ignorerons ces faits physiques gênants pour une pure précision mathamatique!

3
ggb667

Il n'y a aucun gain de performances.

Cependant, si ces constantes correspondent à certains bits en dessous, la plupart des programmeurs préfèrent Hex (ou même binaire) pour rendre cela clair et plus lisible.

Par exemple, on peut facilement voir que GL_EXP2 a 2 bits, le 1 bit et le bit 0x0800 (qui est 2048 décimal). Une valeur décimale de 2049 serait moins claire.

2
user949300

Parfois, il est plus facile d'utiliser des algorithmes liés aux bits. D'autres fois, il traite des comparaisons de bits, comme ma déclaration dans un commentaire, 4 bits (chiffres binaires) se convertissent en 1 lettre hexadécimale, donc, A3 = 10100011.

D'autres fois, c'est amusant ou brise la monotonie, bien que les gens qui ne connaissent pas l'hexagone puissent penser que vous faites des choses avec des pointeurs

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

Je l'utilise parfois pour vérifier les limites de choses comme les pouces. Par exemple, vous pouvez utiliser 0x7FFFFFFF (0x80000000 fonctionne dans de nombreux cas mais 0x7F ... est plus sûr) pour obtenir un nombre maximal de bornes int. C'est pratique pour définir une constante d'erreur très élevée si vous n'avez pas une langue qui a quelque chose comme MAX_INT. La technique évolue également, car pour 64 bits, vous pouvez utiliser 0x7FFFFFFFFFFFFFFF. Vous pouvez remarquer que Android utilise 0x7 ___ pour les recherches de table R.id.

Je parie qu'ils le font par souci de clarté. Vous pouvez facilement utiliser des entiers, mais si vous êtes familier avec l'hexagone, ce n'est pas mauvais. Il semble qu'ils réservent des valeurs x pour certaines fonctions. En décimal, vous feriez quelque chose comme 0-99 est des erreurs, 100-199 pour autre chose, etc. La façon dont ils le font est mise à l'échelle différemment.

En termes de performances, vous ne gagnez rien à l'exécution car le compilateur (même un grand nombre d'assembleurs) convertit à la fin n'importe quel format en binaire, qu'il soit décimal, octal, hexadécimal, flottant, double, etc.

1
Joe Plante