Pourquoi utiliser des constantes hexadécimales?

Parfois, je vois des constantes entières définies en hexadécimal, au lieu de nombres décimaux. C’est une petite partie que j’ai prise d’une classe 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 , donc y a-t-il un gain de performance? Je ne le pense pas vraiment, car le compilateur devrait alors le changer.

Il est probable pour la propreté organisationnelle et visuelle. La base 16 a une relation beaucoup plus simple avec le binary 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 en commun seraient moins clairs. S’ils avaient plutôt des chiffres décimaux en commun, les modèles de bits n’auraient pas le même degré de similarité.

De plus, dans de nombreuses situations, il est souhaitable de pouvoir assembler des constantes OU pour créer une combinaison de drapeaux. Si la valeur de chaque constante est limitée à un sous-ensemble des bits non nuls, cela peut être fait d’une manière pouvant être re-séparée. L’utilisation de constantes hexadécimales indique clairement quels bits ne sont pas nuls dans chaque valeur.

Il existe deux autres possibilités raisonnables: octal ou base 8 encode simplement 3 bits par chiffre. Et puis, il y a un nombre décimal codé en binary, dans lequel chaque chiffre nécessite quatre bits, mais les valeurs numériques supérieures à 9 sont interdites – cela serait désavantageux car il ne peut pas représenter toutes les possibilités possibles.

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

Je ne sais pas à propos de ce cas particulier, mais très souvent, ce n’est pas vrai.

Sur les deux questions:

  • A) Quelle est la valeur du bit de 2914?
  • B) Quelle est la valeur de bit de 0x0B62?

B répondra plus rapidement plus rapidement par beaucoup de développeurs. (Cela vaut aussi pour les questions similaires)


0x0B62 (il y a 4 chiffres hexadécimaux de sorte qu’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 te défie de faire la même chose avec 2914.)


C’est une des raisons d’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 = ...; 

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

Lisibilité lors de l’application de masques hexadécimaux, par exemple.

Il n’y aura pas de gain de performance 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 binarys. Hexadécimal mappe très proprement en binary, mais il faut un peu de travail pour convertir un nombre décimal en binary.

L’un des endroits où la valeur hexadécimale brille est lorsque vous avez un certain nombre d’éléments connexes, dont 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 les nombres décimaux, il serait difficile de “noter” les régions constantes de bits sur un grand nombre d’éléments différents, mais liés.

0xFFFFFFFF -vous écrire 0xFFFFFFFF ou 4294967295 ?

Le premier représente beaucoup plus clairement un type de données 32 bits avec tous les types. Bien sûr, beaucoup de programmeurs expérimentés reconnaîtront ce dernier modèle et auront un soupçon discret quant à sa véritable signification. Cependant, même dans ce cas, il est beaucoup plus enclin aux erreurs de frappe, etc.

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

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

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

Hexadécimal est le format lisible le plus proche du format binary. Cela simplifie beaucoup les opérations bit par exemple

0xB62 est égal à 2914 🙂

Pour les développeurs, il est beaucoup plus facile d’imaginer mentalement le modèle de bits d’une constante quand elle est présentée en hexadécimal que lorsque celle-ci est présentée sous la forme d’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 indicateurs individuels par exemple) sont pertinents.

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

Pour Couleurs hexadécimal 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 sous forme de nombres (bien que le gamma et la fidélité de l’œil humain aient tendance à jeter les choses, ces faits physiques gênants pour une précision purement mathématique!

Il n’y a pas de gain de performance.

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

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

Parfois, il est plus facile d’utiliser des algorithmes liés aux bits. D’autres fois, il s’agit de comparaisons de bits, comme mon énoncé dans un commentaire, 4 bits (chiffres binarys) convertis en 1 lettre hexadécimale, donc, A3 = 10100011.

D’autres fois, c’est amusant ou casse la monotonie, bien que les personnes qui ne sont pas familières avec hex 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 ints. Par exemple, vous pouvez utiliser 0x7FFFFFFF (0x80000000 fonctionne dans de nombreux cas, mais le 0x7F … est plus sûr) pour obtenir un nombre maximal de limites int. Il est pratique de définir une constante d’erreur très élevée si vous ne disposez pas d’un langage ayant quelque chose comme MAX_INT. La technique évolue également, puisque pour 64 bits, vous pouvez utiliser 0x7FFFFFFFFFFFFFFF. Vous remarquerez peut-être qu’Android utilise 0x7_ __ pour les recherches de tables R.id.

Je parie qu’ils le font pour la clarté. Vous pouvez facilement utiliser des entiers, mais si vous êtes familier avec l’hex, ce n’est pas mal. Il semble qu’ils réservent des valeurs x pour certaines fonctions. En décimal, vous feriez quelque chose comme 0-99 pour les erreurs, 100-199 pour autre chose, etc. La façon dont ils le font est redimensionnée différemment.

Du sharepoint vue des performances, vous ne gagnez rien à l’exécution, car le compilateur (même de nombreux assembleurs) convertit le format en binary à la fin, qu’il soit décimal, octal, hexadécimal, flottant, double, etc.