Como converter decimal em hexadecimal em JavaScript


1479

Como você converte valores decimais em seus equivalentes hexadecimais em JavaScript?


7
Apenas um aviso aqui de que você está iniciando a partir de uma representação de string é muito fácil perder precisão quando você o transforma em Number como parte da conversão para hexadecimal. Veja danvk.org/wp/2012-01-20/… .
precisa saber é o seguinte

Esta função é exatamente o que você precisa
Mohammad Musavi

Respostas:


2475

Converta um número em uma sequência hexadecimal com:

hexString = yourNumber.toString(16);

E inverta o processo com:

yourNumber = parseInt(hexString, 16);

42
yourNum é uma string hexadecimal neste caso. Por exemplo, (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul

8
@forste, você não "perderá precisão" se converter um número javascript (que é um objeto Number, que no script ECMA é um Double) para hexadecimal e vice-versa usando esta técnica. A pergunta que você vinculou refere-se especificamente a números grandes demais para caberem em um Double (daí a representação de string na pergunta). Se você tiver um número, isso funcionará. Se você tem algo grande demais para ser um objeto Number javascript (a Double), precisará encontrar outra coisa.
Prestaul 30/03/12

12
@ Derek, eu tenho um problema psicológico que não me permitirá tolerar parênteses desnecessários ... @ todo mundo, yourNumberé uma variável. Se você quiser usar um literal numérico, precisará fazer algo como (45).toString(16), mas se estiver codificando um número, escreva-o como uma sequência hexadecimal ... (45).toString(16)sempre será igual '2d', portanto, não desperdice a CPU ciclos para descobrir isso.
Prestaul

21
@Prestaul "Não desperdice ciclos de CPU para descobrir isso" - isso é chamado de otimização prematura. A menos que o JavaScript esteja sendo executado em um 286, duvido que a sobrecarga seja importante. Além disso, '45' pode ser um número mágico que o programador precisa ser capaz de reconhecer (como a duração do tempo limite em segundos), enquanto '2d', bem, quem reconhecerá isso?
DeJay Clayton

47
Se você não gosta dos parênteses, basta usar um ponto extra:42..toString(16)
Thomas Watson

142

Se você precisar lidar com coisas como campos de bits ou cores de 32 bits, precisará lidar com números assinados. A função JavaScript toString(16)retornará um número hexadecimal negativo que geralmente não é o que você deseja. Esta função faz alguma adição maluca para torná-la um número positivo.

function decimalToHexString(number)
{
  if (number < 0)
  {
    number = 0xFFFFFFFF + number + 1;
  }

  return number.toString(16).toUpperCase();
}

console.log(decimalToHexString(27));
console.log(decimalToHexString(48.6));


5
isso é complemento para dois?
Julian

2
Normalmente, essa conversão não é necessária, pois o JavaScript pode representar todos os campos de 32 bits como números não assinados (consulte Number.MAX_SAFE_INTEGER). Pela mesma razão, a conversão em não assinada pode ser escrita como:number = 0x100000000 + number;
Johannes Matokic 22/10

3
Uma observação resumida no meu comentário anterior: Embora a representação hexadecimal funcione para números até Number.MAX_SAFE_INTEGER, isso não vale para operações bit a bit (que geralmente são usadas para criar cores de 32 bits). O resultado de operações bit a bit é sempre um número inteiro de 32 bits assinado. Portanto, os resultados bit a bit> = 2 ^ 31 são negativos e 0x100000000 | 0 === 0.
Johannes Matokic

25
Você pode usar o >>>operador para converter o número em representação não assinada, por exemplo, ((-3253) >>> 0).toString(16)retornos "fffff34b".
Csharpfolk

1
+1para uma adição útil, mas se você estiver convertendo números para uma notação diferente, todos os números já são "geralmente" positivos, ou você deseja resultados negativos.
Carl Smith

82

O código abaixo converterá o valor decimal d em hexadecimal. Também permite adicionar preenchimento ao resultado hexadecimal. Portanto, 0 se tornará 00 por padrão.

function decimalToHex(d, padding) {
    var hex = Number(d).toString(16);
    padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

    while (hex.length < padding) {
        hex = "0" + hex;
    }

    return hex;
}

5
Isso não manipula corretamente valores negativos. decimalToHex (-6, 4) retornaria 00-6.
JonMR

3
Ele também tem problemas com flutuadores, mas colocar Math.round () corrigiu isso. (+ 1ed)
Michael - Onde está Clay Shirky,

Estou "puxando" números de uma matriz ('255,0,55', etc) e o .toString (16) não funcionou. Tudo o que consegui foram os mesmos números! Eu adicionei a função "Number" à frente e agora funciona! Passamos apenas quatro horas tentando encontrar a solução !!
Cristofayre

65
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}

1
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Lori

2
Não é tão difícil estendê-lo, você está cortando os últimos dígitos com .slice (-number) lá. Se você adicionar mais zeros à frente, funcionará bem.
Tatarize

19
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')😁
Ninh Pham

39

Para completar, se você deseja a representação hexadecimal de dois números complementares de um número negativo, pode usar o operador de deslocamento com zero e preenchimento à direita>>> . Por exemplo:

> (-1).toString(16)
"-1"

> ((-2)>>>0).toString(16)
"fffffffe"

No entanto, há uma limitação: os operadores bit a bit do JavaScript tratam seus operandos como uma sequência de 32 bits , ou seja, você obtém o complemento de dois bits de 32 bits.


2
este é, de longe, a resposta valiosa mais a esta pergunta :)
albertjan

Vasculhando todas as perguntas porque C# number to hexadecimalestava produzindo resultados diferentes para Javascript number to hexadecimal. Parece que o Javascript está com problemas com números negativos. Esta resposta parece ser a solução para o problema.
goamn

Isso foi extremamente útil, obrigado! Eu estava usando isso para as cores RGB, de modo a obter a variante de 24-bit, pique dos dois primeiros caracteres (o FF adicional) -((-2)>>>0).toString(16).substring(2)
antonyh

36

Com estofamento:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}

2
@ Lucas Retorna os últimos 4 caracteres.
Gabriel

19

Sem o loop:

function decimalToHex(d) {
  var hex = Number(d).toString(16);
  hex = "000000".substr(0, 6 - hex.length) + hex;
  return hex;
}

// Or "#000000".substr(0, 7 - hex.length) + hex;
// Or whatever
// *Thanks to MSDN

Também não é melhor não usar testes de loop que precisam ser avaliados?

Por exemplo, em vez de:

for (var i = 0; i < hex.length; i++){}

ter

for (var i = 0, var j = hex.length; i < j; i++){}

19

Combinando algumas dessas boas idéias para uma função de valor RGB para hexadecimal (adicione o #restante em HTML / CSS):

function rgb2hex(r,g,b) {
    if (g !== undefined)
        return Number(0x1000000 + r*0x10000 + g*0x100 + b).toString(16).substring(1);
    else
        return Number(0x1000000 + r[0]*0x10000 + r[1]*0x100 + r[2]).toString(16).substring(1);
}

Obrigado por isso! Eu gostaria de deixar um comentário há muito tempo. Foi a chave da minha resposta. stackoverflow.com/questions/5560248/…
Pimp Trizkit

16

A resposta aceita não levou em consideração códigos hexadecimais retornados por um dígito. Isso é facilmente ajustado por:

function numHex(s)
{
    var a = s.toString(16);
    if ((a.length % 2) > 0) {
        a = "0" + a;
    }
    return a;
}

e

function strHex(s)
{
    var a = "";
    for (var i=0; i<s.length; i++) {
        a = a + numHex(s.charCodeAt(i));
    }

    return a;
}

Acredito que as respostas acima foram postadas várias vezes por outras pessoas, de uma forma ou de outra. Envolvo-os em uma função toHex () da seguinte forma:

function toHex(s)
{
    var re = new RegExp(/^\s*(\+|-)?((\d+(\.\d+)?)|(\.\d+))\s*$/);

    if (re.test(s)) {
        return '#' + strHex( s.toString());
    }
    else {
        return 'A' + strHex(s);
    }
}

Observe que a expressão regular numérica veio de mais de 10 funções úteis de expressão regular de JavaScript para melhorar a eficiência de seus aplicativos da web .

Atualização: Depois de testar isso várias vezes, encontrei um erro (aspas duplas no RegExp), então resolvi isso. CONTUDO! Depois de bastante teste e de ter lido o post por almaz - percebi que não conseguia obter números negativos para o trabalho.

Além disso - fiz algumas leituras sobre isso e, como todos os números JavaScript são armazenados como palavras de 64 bits, não importa o quê - tentei modificar o código numHex para obter a palavra de 64 bits. Mas acontece que você não pode fazer isso. Se você colocar "3.14159265" COMO NÚMERO em uma variável - tudo o que conseguirá obter é o "3", porque a parte fracionária só é acessível multiplicando o número por dez (IE: 10.0) repetidamente. Ou, colocando de outra maneira - o valor hexadecimal de 0xF faz com que o valor do ponto flutuante seja convertido em um número inteiro antes de ser ANDed, o que remove tudo o que está atrás do período. Em vez de pegar o valor como um todo (ou seja: 3,14159265) e ANDing do ponto flutuante valor do contra o valor 0xF.

Portanto, a melhor coisa a fazer, nesse caso, é converter o 3,14159265 em uma sequência e depois apenas converter a sequência. Por causa do exposto, também facilita a conversão de números negativos porque o sinal de menos se torna 0x26 na frente do valor.

Então, o que eu fiz foi determinar que a variável contém um número - basta convertê-lo em uma string e converter a string. Isso significa para todos que, no lado do servidor, você precisará unx da cadeia de caracteres recebida e, em seguida, determinar que as informações recebidas são numéricas. Você pode fazer isso facilmente adicionando um "#" na frente dos números e "A" na frente de uma sequência de caracteres retornando. Veja a função toHex ().

Diverta-se!

Depois de mais um ano e muito pensamento, decidi que a função "toHex" (e também tenho a função "fromHex") realmente precisava ser reformada. A questão toda era "Como posso fazer isso com mais eficiência?" Decidi que uma função hexadecimal de / para não deveria se importar se algo é uma parte fracionária, mas ao mesmo tempo deve garantir que partes fracionárias sejam incluídas na string.

Então a pergunta tornou-se: "Como você sabe que está trabalhando com uma cadeia hexadecimal?". A resposta é simples. Use as informações pré-string padrão que já são reconhecidas em todo o mundo.

Em outras palavras - use "0x". Então agora minha função toHex procura ver se ela já está lá e se está - apenas retorna a string que foi enviada a ela. Caso contrário, ele converte a string, número, qualquer que seja. Aqui está a função toHex revisada:

/////////////////////////////////////////////////////////////////////////////
//  toHex().  Convert an ASCII string to hexadecimal.
/////////////////////////////////////////////////////////////////////////////
toHex(s)
{
    if (s.substr(0,2).toLowerCase() == "0x") {
        return s;
    }

    var l = "0123456789ABCDEF";
    var o = "";

    if (typeof s != "string") {
        s = s.toString();
    }
    for (var i=0; i<s.length; i++) {
        var c = s.charCodeAt(i);

        o = o + l.substr((c>>4),1) + l.substr((c & 0x0f),1);
    }

    return "0x" + o;
}

Essa é uma função muito rápida que leva em conta dígitos únicos, números de ponto flutuante e até verifica se a pessoa está enviando um valor hexadecimal para ser hexadecimal novamente. Ele usa apenas quatro chamadas de função e apenas duas delas estão no loop. Para cancelar a hex os valores que você usa:

/////////////////////////////////////////////////////////////////////////////
//  fromHex().  Convert a hex string to ASCII text.
/////////////////////////////////////////////////////////////////////////////
fromHex(s)
{
    var start = 0;
    var o = "";

    if (s.substr(0,2).toLowerCase() == "0x") {
        start = 2;
    }

    if (typeof s != "string") {
        s = s.toString();
    }
    for (var i=start; i<s.length; i+=2) {
        var c = s.substr(i, 2);

        o = o + String.fromCharCode(parseInt(c, 16));
    }

    return o;
}

Como a função toHex (), a função fromHex () primeiro procura o "0x" e depois converte as informações recebidas em uma sequência, se ainda não for uma sequência. Eu não sei como não seria uma corda - mas apenas no caso - eu verifico. A função então é executada, capturando dois caracteres e convertendo-os em caracteres ASCII. Se você quiser traduzir Unicode, precisará alterar o loop para passar por quatro (4) caracteres por vez. Mas também é necessário garantir que a sequência NÃO seja divisível por quatro. Se for - então é uma sequência hexadecimal padrão. (Lembre-se de que a string tem "0x" na frente.)

Um script de teste simples para mostrar que -3,14159265, quando convertido em uma sequência, ainda é -3,14159265.

<?php

    echo <<<EOD
<html>
    <head><title>Test</title>
        <script>
            var a = -3.14159265;
            alert( "A = " + a );
            var b = a.toString();
            alert( "B = " + b );
        </script>
    </head>
    <body>
    </body>
</html>
EOD;

?>

Por causa de como o JavaScript funciona em relação à função toString (), todos esses problemas podem ser eliminados e que antes estavam causando problemas. Agora todas as seqüências e números podem ser convertidos facilmente. Além disso, coisas como objetos farão com que um erro seja gerado pelo próprio JavaScript. Eu acredito que isso é tão bom quanto ele ganha. A única melhoria que resta é que o W3C inclua apenas uma função toHex () e fromHex () no JavaScript.


Acho que você ainda tem trabalho a fazer aqui ... if( s.substr(0,2)antes if (typeof s != "string")provavelmente não é o que você quer, por exemplo. O que eu havia retornado não era o que eu esperava ( toHex(0x1f635)"0x313238353635"). Não investiguei mais.
ruffin

Eu acredito que você está incorreto. Seu exemplo está usando uma sequência hexadecimal que NÃO é uma sequência - mas um número. Portanto, o 1f635 sairia do jeito que está. Se você tivesse colocado "0x1f635", o resultado seria diferente. (ou seja: a rotina teria acabado de voltar o número hexadecimal que você tinha enviado para a rotina.) :-)
Mark Manning

O primeiro ponto foi que você não pode usar o substr& toLowerCaseem uma não-string ... então, é typeofnecessário que chegue mais cedo ou, se você esperava toHexlançar uma não-string ali, remova a typeofverificação completamente. Faz sentido? Ou seja, se eu usasse o código aqui sem edições e telefonasse toHex(0x1f635), receberia Uncaught TypeError: s.substr is not a function. Se eu mover a corda lançada mais cedo, você está certo, o número é convertido em decimal primeiro, talvez, e as coisas vão para o lado. O que, obviamente, significa que você não pode fazer uma conversão simples aqui se snão for uma string.
Ruffin

Na verdade, no XP, isso funciona bem. Houve várias atualizações no Javascript que estão tornando o Javascript tipográfico. O que lançaria uma exceção. No XP, ele funciona. Pelo menos para mim. Em um mundo tipográfico, colocar "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}" é apropriado. Mas ox1f635 ainda não é uma string. :-)
Mark Manning

12
var number = 3200;
var hexString = number.toString(16);

O 16 é a raiz e existem 16 valores em um número hexadecimal :-)


12

Para qualquer pessoa interessada, aqui está um JSFiddle comparando a maioria das respostas dadas a esta pergunta .

E aqui está o método que eu acabei usando:

function decToHex(dec) {
  return (dec + Math.pow(16, 6)).toString(16).substr(-6)
}

Além disso, lembre-se de que, se você deseja converter de decimal para hexadecimal para uso em CSS como um tipo de dados em cores , pode preferir extrair os valores RGB do decimal e usar rgb () .

Por exemplo ( JSFiddle ):

let c = 4210330 // your color in decimal format
let rgb = [(c & 0xff0000) >> 16,  (c & 0x00ff00) >> 8,  (c & 0x0000ff)]

// Vanilla JS:
document..getElementById('some-element').style.color = 'rgb(' + rgb + ')'
// jQuery:
$('#some-element').css('color', 'rgb(' + rgb + ')')

Isso define #some-elementa colorpropriedade CSS de rgb(64, 62, 154).


10

Restringido / preenchido para um número definido de caracteres:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}

2
Isso converte um número em uma string hexadecimal E apaga zeros à esquerda, isso é lindo!
Gordon

10

Aqui está uma versão reduzida do ECMAScript 6:

const convert = {
  bin2dec : s => parseInt(s, 2).toString(10),
  bin2hex : s => parseInt(s, 2).toString(16),
  dec2bin : s => parseInt(s, 10).toString(2),
  dec2hex : s => parseInt(s, 10).toString(16),
  hex2bin : s => parseInt(s, 16).toString(2),
  hex2dec : s => parseInt(s, 16).toString(10)
};

convert.bin2dec('111'); // '7'
convert.dec2hex('42');  // '2a'
convert.hex2bin('f8');  // '11111000'
convert.dec2bin('22');  // '10110'

Em forte desacordo com o @HypersoftSystems, se seu ambiente ou situação permitir, use o ES6. Nem todo script precisa ser executado em intérpretes de bootleg herdados, mas o babel existe por um motivo. E, finalmente, o ES6 é muito mais legível, se você souber. Dito isto, fornecer respostas JS padrão poderia ajudar mais pessoas, mas considerando que existem outras respostas para versões JS mais antigas, ter uma resposta ES6 é apenas benéfico, o discurso "foi assim que eu fiz isso no passado" definitivamente não é necessário.
WiR3D 12/12

As opiniões não revelam fatos, portanto seu "argumento" é inválido. @ WiR3D
Hypersoft Systems

O @HypersoftSystems é tão válido quanto o seu, se não mais, pois o seu é igualmente opinativo e limita o contexto a um contexto que provavelmente é inválido na maioria dos aplicativos modernos.
WiR3D

erro do usuário: "exatamente como opinou", "provavelmente" e "a maioria".
Hypersoft Systems

9
function dec2hex(i)
{
  var result = "0000";
  if      (i >= 0    && i <= 15)    { result = "000" + i.toString(16); }
  else if (i >= 16   && i <= 255)   { result = "00"  + i.toString(16); }
  else if (i >= 256  && i <= 4095)  { result = "0"   + i.toString(16); }
  else if (i >= 4096 && i <= 65535) { result =         i.toString(16); }
  return result
}

1
+1 obrigado! Ao trabalhar com CSS, o toString (16) é importante para que você obtenha resultados como FF0000
Tyler Egeto 21/02

7
ao trabalhar com css (ou svg, que aceita especificações de cores no estilo css), você pode contornar todo o problema escrevendo color: rgb(r,g,b)onde rg e b são números decimais.
telent 27/02

1
Deve ser:function decimalToHexString(i) { var result = "00"; if (i >= 0 && i <= 15) { result += "000" + i.toString(16); } else if (i >= 16 && i <= 255) { result += "00" + i.toString(16); } else if (i >= 256 && i <= 4095) { result += "0" + i.toString(16); } else if (i >= 4096 && i <= 65535) { result += i.toString(16); } return result }
Aykut Çevik

9

Se você deseja converter um número em uma representação hexadecimal de um valor de cor RGBA, achei a combinação mais útil de várias dicas daqui:

function toHexString(n) {
    if(n < 0) {
        n = 0xFFFFFFFF + n + 1;
    }
    return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}

8

O comentário AFAIK 57807 está errado e deve ser algo como: var hex = Number (d) .toString (16); em vez de var hex = parseInt (d, 16);

function decimalToHex(d, padding) {
    var hex = Number(d).toString(16);
    padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

    while (hex.length < padding) {
        hex = "0" + hex;
    }

    return hex;
}

6

E se o número for negativo?

Aqui está a minha versão.

function hexdec (hex_string) {
    hex_string=((hex_string.charAt(1)!='X' && hex_string.charAt(1)!='x')?hex_string='0X'+hex_string : hex_string);
    hex_string=(hex_string.charAt(2)<8 ? hex_string =hex_string-0x00000000 : hex_string=hex_string-0xFFFFFFFF-1);
    return parseInt(hex_string, 10);
}

5

Estou fazendo a conversão para string hexadecimal em um loop bastante grande, então tentei várias técnicas para encontrar a mais rápida. Meus requisitos eram ter uma sequência de comprimento fixo como resultado e codificar valores negativos corretamente (-1 => ff..f).

Simples .toString(16)não funcionou para mim, pois eu precisava que valores negativos fossem codificados corretamente. O código a seguir é o mais rápido que testei até agora em valores de 1-2 bytes (observe que symbolsdefine o número de símbolos de saída que você deseja obter, ou seja, para um número inteiro de 4 bytes, deve ser igual a 8):

var hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
function getHexRepresentation(num, symbols) {
    var result = '';
    while (symbols--) {
        result = hex[num & 0xF] + result;
        num >>= 4;
    }
    return result;
}

Ele executa mais rápido que .toString(16)em números de 1-2 bytes e mais lento em números maiores (quando symbols> = 6), mas ainda deve superar os métodos que codificam valores negativos corretamente.


5

Como declara a resposta aceita, a maneira mais fácil de converter de decimal para hexadecimal é var hex = dec.toString(16). No entanto, você pode preferir adicionar uma conversão de string, pois garante que as representações de string "12".toString(16)funcionem corretamente.

// Avoids a hard-to-track-down bug by returning `c` instead of `12`
(+"12").toString(16);

Para reverter o processo, você também pode usar a solução abaixo, pois ela é ainda mais curta.

var dec = +("0x" + hex);

Parece ser mais lento no Google Chrome e Firefox, mas é significativamente mais rápido no Opera. Consulte http://jsperf.com/hex-to-dec .


5

Como converter decimal em hexadecimal em JavaScript

Não consegui encontrar uma conversão brutalmente limpa / decimal em hexadecimal que não envolvesse uma bagunça de funções e matrizes ... então tive que fazer isso por mim mesma.

function DecToHex(decimal) { // Data (decimal)

    length = -1;    // Base string length
    string = '';    // Source 'string'

    characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]; // character array

    do { // Grab each nibble in reverse order because JavaScript has no unsigned left shift

        string += characters[decimal & 0xF];   // Mask byte, get that character
        ++length;                              // Increment to length of string

    } while (decimal >>>= 4); // For next character shift right 4 bits, or break on 0

    decimal += 'x'; // Convert that 0 into a hex prefix string -> '0x'

    do
        decimal += string[length];
    while (length--); // Flip string forwards, with the prefixed '0x'

    return (decimal); // return (hexadecimal);
}

/* Original: */

D = 3678;    // Data (decimal)
C = 0xF;    // Check
A = D;        // Accumulate
B = -1;        // Base string length
S = '';        // Source 'string'
H = '0x';    // Destination 'string'

do {
    ++B;
    A& = C;

    switch(A) {
        case 0xA: A='A'
        break;

        case 0xB: A='B'
        break;

        case 0xC: A='C'
        break;

        case 0xD: A='D'
        break;

        case 0xE: A='E'
        break;

        case 0xF: A='F'
        break;

        A = (A);
    }
    S += A;

    D >>>= 0x04;
    A = D;
} while(D)

do
    H += S[B];
while (B--)

S = B = A = C = D; // Zero out variables
alert(H);    // H: holds hexadecimal equivalent

5
Oh meu ... essa é uma maneira realmente terrível e horrível de fazer isso, feita com um estilo de codificação ainda mais feio. Honestamente: o que há de errado com quebras de linha e indentação? Variáveis ​​de letra única? Mesmo?
Victor Schröder

1
Revisou. Isso é horrível? E o estilo é melhor? Inicialmente eu pensei que seria mais fácil de entender com cada passo "literalmente" soletrou para fora como aquele com letras ... às vezes eu posso ser muito estúpido
JonLikeSquirrel

4
Desculpe, sim, ainda é terrível. Seu código ainda usa muitos loops ineficientes e polui o espaço para nome global, entre outros problemas. A abordagem em si é um exagero para uma tarefa que pode ser realizada com uma simples chamada de função. Se você deseja melhorar seu estilo de codificação em JS, recomendo vivamente que leia materiais como w3.org/wiki/JavaScript_best_practices e google.github.io/styleguide/javascriptguide.xml . Basta pesquisar no Google sobre o assunto.
Victor Schröder

1
Fiz um teste de velocidade no Chrome e minha função de exagero é cerca de 30% mais rápida que .toString (16), enquanto no Firefox minha função é 40% mais lenta que .toString (16) ... O Chrome prova que meus loops excessivos são mais eficientes do que a função nativa .toString (16) dos navegadores, enquanto o Firefox prova por que mais pessoas preferem o Chrome. Ou isso é ao contrário? Um dia, o Chrome pode até atualizar para um .toString (16) mais rápido, tornando-me incorreto nos dois casos! De qualquer maneira, não estou completamente errado, e você não está totalmente certo. Meu ego de lado, no entanto, entendi pelo menos 30% dele. ;)
JonLikeSquirrel

2
Você nunca precisa declarar uma matriz de cadeias contendo caracteres únicos cada. Apenas declare uma cadeia de caracteres. Você pode obter um caractere de uma string da mesma forma que faria com uma matriz, usando colchetes.
David Spector

3

Para resumir tudo;

function toHex(i, pad) {

  if (typeof(pad) === 'undefined' || pad === null) {
    pad = 2;
  } 

  var strToParse = i.toString(16);

  while (strToParse.length < pad) {
    strToParse = "0" + strToParse;
  }

  var finalVal =  parseInt(strToParse, 16);

  if ( finalVal < 0 ) {
    finalVal = 0xFFFFFFFF + finalVal + 1;
  }

  return finalVal;
}

No entanto, se você não precisar convertê-lo novamente em um número inteiro no final (por exemplo, para cores), basta garantir que os valores não sejam negativos.


2

Não encontrei uma resposta clara, sem verificações se é negativa ou positiva, que usa o complemento de dois (números negativos incluídos). Para isso, mostro minha solução para um byte:

((0xFF + number +1) & 0x0FF).toString(16);

Você pode usar esta instrução para qualquer número de bytes, apenas você adiciona FFnos respectivos lugares. Por exemplo, para dois bytes:

((0xFFFF + number +1) & 0x0FFFF).toString(16);

Se você deseja converter um número inteiro da matriz na cadeia hexadecimal:

s = "";
for(var i = 0; i < arrayNumber.length; ++i) {
    s += ((0xFF + arrayNumber[i] +1) & 0x0FF).toString(16);
}

2

Caso pretenda converter em uma representação JavaScript ou CSS 'completa', você pode usar algo como:

  numToHex = function(num) {
    var r=((0xff0000&num)>>16).toString(16),
        g=((0x00ff00&num)>>8).toString(16),
        b=(0x0000ff&num).toString(16);
    if (r.length==1) { r = '0'+r; }
    if (g.length==1) { g = '0'+g; }
    if (b.length==1) { b = '0'+b; }
    return '0x'+r+g+b;                 // ('#' instead of'0x' for CSS)
  };

  var dec = 5974678;
  console.log( numToHex(dec) );        // 0x5b2a96


1

Se você estiver procurando pela conversão de números inteiros grandes, ou seja, números maiores que Number.MAX_SAFE_INTEGER - 9007199254740991, use o seguinte código

const hugeNumber = "9007199254740991873839" // Make sure its in String
const hexOfHugeNumber = BigInt(hugeNumber).toString(16);
console.log(hexOfHugeNumber)


1

Isso é baseado nas soluções da Prestaul e Tod. No entanto, essa é uma generalização que explica o tamanho variável de uma variável (por exemplo, Analisando o valor assinado de um log serial do microcontrolador).

function decimalToPaddedHexString(number, bitsize)
{ 
  let byteCount = Math.ceil(bitsize/8);
  let maxBinValue = Math.pow(2, bitsize)-1;

  /* In node.js this function fails for bitsize above 32bits */
  if (bitsize > 32)
    throw "number above maximum value";

  /* Conversion to unsigned form based on  */
  if (number < 0)
    number = maxBinValue + number + 1;

  return "0x"+(number >>> 0).toString(16).toUpperCase().padStart(byteCount*2, '0');
}

Script de teste:

for (let n = 0 ; n < 64 ; n++ ) { 
     let s=decimalToPaddedHexString(-1, n); 
     console.log(`decimalToPaddedHexString(-1,${(n+"").padStart(2)}) = ${s.padStart(10)} = ${("0b"+parseInt(s).toString(2)).padStart(34)}`);
   }

Resultado dos testes:

decimalToPaddedHexString(-1, 0) =        0x0 =                                0b0
decimalToPaddedHexString(-1, 1) =       0x01 =                                0b1
decimalToPaddedHexString(-1, 2) =       0x03 =                               0b11
decimalToPaddedHexString(-1, 3) =       0x07 =                              0b111
decimalToPaddedHexString(-1, 4) =       0x0F =                             0b1111
decimalToPaddedHexString(-1, 5) =       0x1F =                            0b11111
decimalToPaddedHexString(-1, 6) =       0x3F =                           0b111111
decimalToPaddedHexString(-1, 7) =       0x7F =                          0b1111111
decimalToPaddedHexString(-1, 8) =       0xFF =                         0b11111111
decimalToPaddedHexString(-1, 9) =     0x01FF =                        0b111111111
decimalToPaddedHexString(-1,10) =     0x03FF =                       0b1111111111
decimalToPaddedHexString(-1,11) =     0x07FF =                      0b11111111111
decimalToPaddedHexString(-1,12) =     0x0FFF =                     0b111111111111
decimalToPaddedHexString(-1,13) =     0x1FFF =                    0b1111111111111
decimalToPaddedHexString(-1,14) =     0x3FFF =                   0b11111111111111
decimalToPaddedHexString(-1,15) =     0x7FFF =                  0b111111111111111
decimalToPaddedHexString(-1,16) =     0xFFFF =                 0b1111111111111111
decimalToPaddedHexString(-1,17) =   0x01FFFF =                0b11111111111111111
decimalToPaddedHexString(-1,18) =   0x03FFFF =               0b111111111111111111
decimalToPaddedHexString(-1,19) =   0x07FFFF =              0b1111111111111111111
decimalToPaddedHexString(-1,20) =   0x0FFFFF =             0b11111111111111111111
decimalToPaddedHexString(-1,21) =   0x1FFFFF =            0b111111111111111111111
decimalToPaddedHexString(-1,22) =   0x3FFFFF =           0b1111111111111111111111
decimalToPaddedHexString(-1,23) =   0x7FFFFF =          0b11111111111111111111111
decimalToPaddedHexString(-1,24) =   0xFFFFFF =         0b111111111111111111111111
decimalToPaddedHexString(-1,25) = 0x01FFFFFF =        0b1111111111111111111111111
decimalToPaddedHexString(-1,26) = 0x03FFFFFF =       0b11111111111111111111111111
decimalToPaddedHexString(-1,27) = 0x07FFFFFF =      0b111111111111111111111111111
decimalToPaddedHexString(-1,28) = 0x0FFFFFFF =     0b1111111111111111111111111111
decimalToPaddedHexString(-1,29) = 0x1FFFFFFF =    0b11111111111111111111111111111
decimalToPaddedHexString(-1,30) = 0x3FFFFFFF =   0b111111111111111111111111111111
decimalToPaddedHexString(-1,31) = 0x7FFFFFFF =  0b1111111111111111111111111111111
decimalToPaddedHexString(-1,32) = 0xFFFFFFFF = 0b11111111111111111111111111111111
Thrown: 'number above maximum value'

Nota: Não sei ao certo por que falha acima de 32 bits


-3

Aqui está a minha solução:

hex = function(number) {
  return '0x' + Math.abs(number).toString(16);
}

A pergunta diz: "Como converter decimal em hexadecimal em JavaScript" . Embora a pergunta não especifique que a cadeia hexadecimal comece com um prefixo 0x, qualquer pessoa que escreva código deve saber que 0x é adicionado aos códigos hexadecimais para distinguir códigos hexadecimais de identificadores programáticos e outros números (1234 pode ser hexadecimal, decimal ou até octal).

Portanto, para responder corretamente a essa pergunta, para fins de escrita de script, você deve adicionar o prefixo 0x.

A função Math.abs (N) converte negativos em positivos e, como bônus, não parece que alguém a executou através de um triturador de madeira.

A resposta que eu queria, teria um especificador de largura de campo, para que pudéssemos, por exemplo, mostrar valores de 8/16 / 32/64 bits da maneira que você os veria listados em um aplicativo de edição hexadecimal. Essa é a resposta correta e real.


1
Na prática geral de codificação, qualquer sequência alfanumérica que comece com uma letra NÃO É UM NÚMERO. Por exemplo: ABCDEF012345678 é um identificador válido em quase todas as linguagens de codificação do planeta.
Hypersoft Systems

1
Ah, e o prefixo 0x não é um problema para javascript: Number('0xFF') === 255;para todos vocês que desejam a operação reversa.
Hypersoft Systems
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.