Por que os números hexadecimais são prefixados com 0x?

414

Por que os números hexadecimais são prefixados como 0x? Entendo o uso do prefixo, mas não entendo o significado do motivo da 0xescolha.

unj2
fonte
9
Agora percebo que o título e o texto fazem duas perguntas completamente diferentes. A maioria das respostas se concentra na pergunta no título. A resposta para a pergunta no texto é simplesmente "não significa nada - é apenas um prefixo dizendo ao compilador que o número inteiro está escrito em hexadecimal".
precisa saber é o seguinte
30
Para ser pedante, também se pode interpretar a pergunta no título de duas maneiras diferentes: 1) "Por que os números hexadecimais são prefixados como 0x, em oposição a qualquer outro prefixo ou indicador?" 2) "Por que precisamos usar um prefixo ao inserir números hexadecimais? Certamente o compilador reconhecerá 58A como um número hexadecimal, mesmo sem o prefixo?" A resposta para a segunda interpretação da pergunta é trivial. "123" também é um número hexadecimal.
precisa saber é o seguinte

Respostas:

440

Breve história: O 0diz ao analisador que está lidando com uma constante (e não um identificador / palavra reservada). Ainda é necessário algo para especificar a base numérica: xé uma escolha arbitrária.

Longa história: Nos anos 60, os sistemas de números de programação predominantes eram decimais e octais - os mainframes tinham 12, 24 ou 36 bits por byte, o que é bem divisível por 3 = log2 (8).

A linguagem BCPL usou a sintaxe 8 1234para números octais. Quando Ken Thompson criou B a partir do BCPL, ele usou o 0prefixo. Isso é ótimo porque

  1. uma constante inteira agora sempre consiste em um único token,
  2. o analisador ainda pode dizer imediatamente que tem uma constante,
  3. o analisador pode informar imediatamente a base ( 0é o mesmo nas duas bases),
  4. é matematicamente são ( 00005 == 05) e
  5. não são necessários caracteres especiais preciosos (como em #123).

Quando C foi criado a partir de B, surgiu a necessidade de números hexadecimais (o PDP-11 tinha palavras de 16 bits) e todos os pontos acima ainda eram válidos. Como os octais ainda eram necessários para outras máquinas, 0xfoi escolhido arbitrariamente ( 00provavelmente foi descartado como estranho).

C # é um descendente de C, portanto herda a sintaxe.

Řrřola
fonte
112
Eu não acho que 0xmais 00estava preferência / constrangimento. 00quebraria o código existente. 0010como octal é 8, enquanto 0010hexadecimal seria 16. Eles não podiam usar nenhum número como um indicador de segundo dígito (exceto 8ou 9, e nenhum possui qualquer significado relacionado ao hexidecimal), portanto, uma letra é obrigatória. E isso deixa um 0hou 0x( H e X idecimal). A partir deste ponto, parece que realmente está de volta à preferência.
GManNickG 12/01
23
Usar um 0prefixo para octal causou muitos problemas ao longo dos anos. Especialmente em países como o Reino Unido, onde os números de telefone começam com a 0. Javascript e muitos outros idiomas os analisariam como octal, confundindo o número antes de armazenar. Para aumentar a diversão, um produto popular de banco de dados mudaria silenciosamente para a análise decimal se o número contivesse um 8ou 9.
Basic
1
12, 24 e 36 também são divisíveis por 4, por que eles não pensaram em hexadecimal para isso?
phuclv
4
@ LưuVĩnhPhúc Provavelmente porque o hexadecimal não era muito relevante. A maior parte do hardware, software e documentação da época se encaixa muito melhor. O BCPL foi implementado pela primeira vez em um IBM 7094 de 36 bits , com um formato de instrução dividido em duas partes de 3 bits e 2 partes de 15 bits; Caracteres de 6 bits; e documentação em octal. As primeiras implementações de B foram em um PDP-7 (18 bits) e um Honeywell GE-945 (36 bits, mas com endereçamento de 18 bits e suporte para bytes de 6 e 9 bits). O PDP-11 de 16 bits saiu após B, então não teria influenciado muito o design de B.
bitbet
97

Nota: Não sei a resposta correta, mas a seguir é apenas minha especulação pessoal!

Como foi mencionado, um 0 antes de um número significa que é octal:

04524 // octal, leading 0

Imagine precisar criar um sistema para indicar números hexadecimais e observe que estamos trabalhando em um ambiente de estilo C. Que tal terminar com h como montagem? Infelizmente você não pode - isso permitiria criar tokens que são identificadores válidos (por exemplo, você poderia nomear uma variável da mesma coisa), o que resultaria em algumas ambiguidades desagradáveis.

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

Você não pode liderar com um personagem pelo mesmo motivo:

xFF00 // also valid identifier

O uso de um hash provavelmente foi descartado porque entra em conflito com o pré-processador:

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

No final, por qualquer motivo, eles decidiram colocar um x depois de um 0 inicial para indicar hexadecimal. É inequívoco, pois ainda começa com um caractere numérico, portanto, não pode ser um identificador válido e provavelmente se baseia na convenção octal de um 0 inicial.

0xFF00 // definitely not an identifier!
AshleysBrain
fonte
3
Interessante. Eu imagino que eles poderiam ter usado um 0 AND à direita para indicar hex. A fuga h provavelmente teriam sido confundido com o sufixo especificador tipo, por exemplo, 0xFF00l vs 0FF00hl
Zdan
2
Esse argumento implica que o uso de um zero à esquerda para indicar números octais antecede o uso do prefixo hexadecimal "0x". Isso é verdade?
Andreas Rejbrand
1
Os dois não foram inventados ao mesmo tempo? Por que haveria um, mas não o outro?
AshleysBrain
AshleysBrain veja a resposta de @ řrřola para saber por que pode haver octal, mas não hexadecimal ao mesmo tempo.
Jv42
2
@zdan eles usaram isso há muito tempo. No assembly Intel x86, um literal hexadecimal sempre deve ser prefixado por 0 se começar com um caractere. Por exemplo, 0xFFAB1234deve ser escrito como 0FFAB1234h. Lembro-me de asm em linha em Pascal quando eu era jovem stackoverflow.com/q/11733731/995714
phuclv
27

É um prefixo para indicar que o número está em hexadecimal e não em outra base. A linguagem de programação C usa-a para informar ao compilador.

Exemplo:

0x6400traduz para 6*16^3 + 4*16^2 + 0*16^1 +0*16^0 = 25600. Quando o compilador lê 0x6400, ele entende que o número é hexadecimal com a ajuda do termo 0x . Geralmente podemos entender por (6400) 16 ou (6400) 8 ou o que for ..

Para binário , seria:

0b00000001

Espero ter ajudado de alguma forma.

Dia bom!

loyola
fonte
2
Literais binários são suportados apenas em C ++ desde C ++ 14 e não são suportados em C.
Ruslan
1
Isso não explica o porquê . Particularmente, por que você não escreveu o primeiro exemplo x6400? O xainda pode ser usado para inferir hexadecimal.
Aaron Franke
12

O 0 anterior é usado para indicar um número na base 2, 8 ou 16.

Na minha opinião, 0x foi escolhido para indicar hexadecimal porque 'x' soa como hexadecimal.

Apenas minha opinião, mas acho que faz sentido.

Dia bom!

Johnny Low
fonte
2
Obrigado pela resposta! Entendo que este é seu primeiro post no StackOverflow. A resposta poderia ter sido mais útil se as opiniões fossem separadas dos fatos.
precisa saber é o seguinte