Pourquoi les nombres hexadécimaux sont-ils préfixés de 0x?

414

Pourquoi les nombres hexadécimaux sont-ils préfixés 0x? Je comprends l'utilisation du préfixe mais je ne comprends pas la signification de pourquoi a 0xété choisi.

unj2
la source
9
Maintenant, je me rends compte que le titre et le texte posent deux questions entièrement différentes. La plupart des réponses se concentrent sur la question dans le titre. La réponse à la question dans le texte est simplement "cela ne veut rien dire - c'est simplement un préfixe indiquant au compilateur que l'entier est écrit en hexadécimal".
Andreas Rejbrand
30
Pour être pédant, on pourrait également interpréter la question dans le titre de deux manières différentes: 1) "Pourquoi les nombres hexadécimaux sont-ils préfixés 0x, par opposition à tout autre préfixe ou indicateur?" 2) "Pourquoi devons-nous utiliser un préfixe lors de la saisie de nombres hexadécimaux? Le compilateur reconnaîtra certainement 58A comme un nombre hexadécimal même sans le préfixe?" La réponse à la deuxième interprétation de la question est triviale. "123" est également un nombre hexadécimal.
Andreas Rejbrand

Réponses:

440

Petite histoire: le 0dit à l'analyseur qu'il s'agit d'une constante (et non d'un identifiant / mot réservé). Quelque chose est encore nécessaire pour spécifier la base numérique: xc'est un choix arbitraire.

Longue histoire: dans les années 60, les systèmes de numéros de programmation répandus étaient décimaux et octaux - les ordinateurs centraux avaient 12, 24 ou 36 bits par octet, ce qui est bien divisible par 3 = log2 (8).

Le langage BCPL utilise la syntaxe 8 1234des nombres octaux. Lorsque Ken Thompson a créé B à partir de BCPL, il a utilisé le 0préfixe à la place. C'est super parce que

  1. une constante entière consiste désormais toujours en un seul jeton,
  2. l'analyseur peut encore dire tout de suite qu'il a une constante,
  3. l'analyseur peut immédiatement dire à la base ( 0est le même dans les deux bases),
  4. il est mathématiquement sain d'esprit ( 00005 == 05), et
  5. aucun précieux caractère spécial n'est nécessaire (comme dans #123).

Lorsque C a été créé à partir de B, le besoin de nombres hexadécimaux est apparu (le PDP-11 avait des mots de 16 bits) et tous les points ci-dessus étaient toujours valables. Étant donné que les octales étaient encore nécessaires pour d'autres machines, a 0xété choisi arbitrairement ( 00a probablement été exclu comme maladroit).

C # est un descendant de C, il hérite donc de la syntaxe.

Řrřola
la source
112
Je ne pense pas 0xplus 00été préférence / maladresses. 00casserait le code existant. 0010comme l'octal est 8, alors 0010que l'hexidécimal serait 16. Ils ne pouvaient pas utiliser n'importe quel nombre comme indicateur de deuxième chiffre (sauf 8ou 9, et ni l'un ni l'autre n'a de signification liée à l'hexidécimal), donc une lettre est un must. Et cela laisse soit 0hou 0x( H e X idecimal). De ce point, il semble que ce soit vraiment de retour à la préférence.
GManNickG
23
L'utilisation d'un 0préfixe pour octal a causé de très nombreux problèmes au fil des ans. Notamment dans des pays comme le Royaume-Uni où les numéros de téléphone commencent par un 0. Javascript et de nombreuses autres langues les analyseraient comme octaux, gommant le nombre avant de le stocker. Pour ajouter au plaisir, un produit de base de données populaire reviendrait silencieusement à l'analyse décimale si le nombre contenait un 8ou 9.
Basic
1
12, 24 et 36 sont également divisibles par 4, alors pourquoi n'ont-ils pas pensé à l'hexadécimal pour cela?
phuclv
4
@ LưuVĩnhPhúc Probablement parce que l'hexadécimal n'était pas très pertinent. La plupart du matériel, des logiciels et de la documentation de l'époque conviennent beaucoup mieux. BCPL a d'abord été implémenté sur un IBM 7094 36 bits , avec un format d'instruction divisé en deux parties 3 bits et 2 parties 15 bits; Caractères 6 bits; et documentation en octal. Les premières implémentations de B étaient sur un PDP-7 (18 bits) et un Honeywell GE-945 (36 bits, mais avec un adressage 18 bits et une prise en charge des octets 6 et 9 bits). Le PDP-11 16 bits est sorti après B, donc n'aurait pas beaucoup influencé la conception de B.
8bittree
97

Remarque: je ne connais pas la bonne réponse, mais ce qui suit n'est que ma spéculation personnelle!

Comme cela a été mentionné, un 0 avant un nombre signifie qu'il est octal:

04524 // octal, leading 0

Imaginez avoir besoin de trouver un système pour désigner les nombres hexadécimaux, et notez que nous travaillons dans un environnement de style C. Que diriez-vous de terminer par h comme assemblage? Malheureusement, vous ne pouvez pas - cela vous permettrait de créer des jetons qui sont des identifiants valides (par exemple, vous pourriez nommer une variable de la même manière), ce qui créerait des ambiguïtés désagréables.

8000h // hex
FF00h // oops - valid identifier!  Hex or a variable or type named FF00h?

Vous ne pouvez pas diriger avec un personnage pour la même raison:

xFF00 // also valid identifier

L'utilisation d'un hachage a probablement été supprimée car elle est en conflit avec le préprocesseur:

#define ...
#FF00 // invalid preprocessor token?

En fin de compte, pour une raison quelconque, ils ont décidé de mettre un x après un 0 de tête pour indiquer hexadécimal. Il n'est pas ambigu car il commence toujours par un caractère numérique et ne peut donc pas être un identifiant valide, et est probablement basé sur la convention octale d'un 0 de tête.

0xFF00 // definitely not an identifier!
AshleysBrain
la source
3
Intéressant. J'imagine qu'ils auraient pu utiliser un 0 et un h de fin pour désigner hex. Le h de fin aurait probablement été confondu avec le suffixe de spécificateur de type, par exemple 0xFF00l vs 0FF00hl
zdan
2
Cet argument implique que l'utilisation d'un zéro non significatif pour désigner des nombres octaux est antérieure à l'utilisation du préfixe hexadécimal "0x". Est-ce vrai?
Andreas Rejbrand
1
N'auraient-ils pas tous deux été inventés en même temps? Pourquoi y en aurait-il un mais pas l'autre?
AshleysBrain
AshleysBrain voit la réponse de @ Řrřola pour savoir pourquoi il pourrait y avoir octal mais pas hexadécimal en même temps.
jv42
2
@zdan ils l'ont utilisé il y a longtemps. Dans un assemblage Intel x86, un littéral hexadécimal doit toujours être préfixé de 0 s'il commence par un caractère. Par exemple, 0xFFAB1234doit être écrit comme 0FFAB1234h. Je m'en souviens depuis asm en ligne dans Pascal quand j'étais jeune stackoverflow.com/q/11733731/995714
phuclv
27

C'est un préfixe pour indiquer que le nombre est en hexadécimal plutôt que dans une autre base. Le langage de programmation C l'utilise pour indiquer au compilateur.

Exemple:

0x6400se traduit par 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. Lorsque le compilateur lit 0x6400, Il comprend que le nombre est hexadécimal à l'aide du terme 0x . Habituellement, nous pouvons comprendre par (6400) 16 ou (6400) 8 ou autre chose.

Pour le binaire, ce serait:

0b00000001

J'espère que j'ai aidé d'une manière ou d'une autre.

Bonne journée!

Loyola
la source
2
Les littéraux binaires ne sont pris en charge qu'en C ++ depuis C ++ 14, et pas du tout pris en charge en C.
Ruslan
1
Cela n'explique pas pourquoi . En particulier, pourquoi ne pourriez-vous pas écrire le premier exemple x6400? Le xpourrait encore être utilisé pour déduire l'hexadécimal.
Aaron Franke
12

Le 0 précédent est utilisé pour indiquer un nombre en base 2, 8 ou 16.

À mon avis, 0x a été choisi pour indiquer hex car «x» sonne comme hex.

Juste mon opinion, mais je pense que cela a du sens.

Bonne journée!

Johnny Low
la source
2
Merci d'avoir répondu! Je comprends que c'est votre premier message sur StackOverflow. La réponse aurait pu être plus utile si les opinions étaient séparées des faits.
vivek_ganesan