Como converter decimal em hexadecimal em JavaScript

1479

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

Luke Smith
fonte
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);
Prestaul
fonte
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));

Tod
fonte
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;
}
Luke Smith
fonte
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()
}
Baznr
fonte
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.

Alberto
fonte
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();
}
Fabio Ferrari
fonte
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++){}
mystifeid
fonte
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);
}
Keith Mashinter
fonte
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.

Mark Manning
fonte
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 :-)

Danny Wilson
fonte
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).

Chapéu
fonte
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();
}
Adamarla
fonte
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'
Humoyun Ahmad
fonte
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
}

fonte
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);
}
coroa
fonte
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;
}
anon
fonte
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);
}
Eliarh
fonte
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.

almaz
fonte
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 .

RD
fonte
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
JonLikeSquirrel
fonte
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.

realkstrawn93
fonte
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);
}
Francisco Manuel Garca Botella
fonte
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
dhc
fonte
2

Você pode fazer algo assim no ECMAScript 6 :

const toHex = num => (num).toString(16).toUpperCase();
Alireza
fonte
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)

Abhilash Nayak
fonte
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

Brian
fonte
-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.

Sistemas Hypersoft
fonte
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