Cómo convertir decimal a hexadecimal en JavaScript

1479

¿Cómo se convierten los valores decimales a su equivalente hexadecimal en JavaScript?

Luke Smith
fuente
77
Solo una advertencia aquí es que está comenzando desde una representación de cadena, es muy fácil perder precisión cuando la convierte en Número como parte de la conversión a hexadecimal. Ver danvk.org/wp/2012-01-20/… .
studgeek
Esta función es exactamente lo que necesita
Mohammad Musavi

Respuestas:

2476

Convierta un número en una cadena hexadecimal con:

hexString = yourNumber.toString(16);

Y revierta el proceso con:

yourNumber = parseInt(hexString, 16);
Prestaul
fuente
42
yourNum es una cadena hexadecimal en este caso. Por ejemplo (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul
8
@forste, no "perderá precisión" si convierte un Número de JavaScript (que es un objeto de Número, que en el script ECMA es Doble) a hexadecimal y viceversa utilizando esta técnica. La pregunta que vinculó hace referencia específicamente a números demasiado grandes para caber en un Doble (de ahí la representación de cadena en la pregunta). Si tienes un número, esto funcionará. Si tiene algo demasiado grande para ser un objeto de Número de JavaScript (un Doble), entonces tendrá que encontrar algo más.
Prestaul
12
@Derek, tengo un problema psicológico que no me permite tolerar paréntesis innecesarios ... @ todos los demás, yourNumberes una variable. Si desea usar un literal numérico, entonces tendrá que hacer algo como (45).toString(16), pero si está codificando un número, escríbalo como una cadena hexadecimal ... (45).toString(16)siempre será igual '2d', así que no desperdicie CPU ciclos para resolver eso.
Prestaul
21
@Prestaul "No malgastes los ciclos de la CPU para resolverlo", eso se llama optimización prematura. A menos que el JavaScript se ejecute en un 286, dudo que los gastos generales sean importantes. Además, '45' podría ser un número mágico que el programador necesita poder reconocer (como la duración del tiempo de espera en segundos), mientras que '2d', ¿quién lo va a reconocer?
Dejay Clayton
47
Si no le gustan los paréntesis, puede usar un punto extra:42..toString(16)
Thomas Watson
142

Si necesita manejar cosas como campos de bits o colores de 32 bits, debe tratar con números con signo. La función de JavaScript toString(16)devolverá un número hexadecimal negativo que generalmente no es lo que desea. Esta función hace una adición loca para que sea un 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
fuente
55
es ese complemento de dos?
Julián
2
Esta conversión normalmente no es necesaria ya que JavaScript puede representar todos los campos de bits de 32 bits como números sin signo (Ver Number.MAX_SAFE_INTEGER). Por la misma razón, la conversión a sin firmar se puede escribir como:number = 0x100000000 + number;
Johannes Matokic
3
Una breve nota sobre mi comentario anterior: si bien la representación hexadecimal debería funcionar para números hasta Number.MAX_SAFE_INTEGER, esto no se cumple para las operaciones bit a bit (que a menudo se usan para crear colores de 32 bits). El resultado de las operaciones bit a bit es siempre un entero de 32 bits con signo. Por lo tanto, los resultados bit a bit> = 2 ^ 31 son negativos y 0x100000000 | 0 === 0.
Johannes Matokic
25
Puede usar el >>>operador para convertir el número a una representación sin signo, por ejemplo, ((-3253) >>> 0).toString(16)devoluciones "fffff34b".
csharpfolk
1
+1para una adición útil, pero si está convirtiendo números a una notación diferente, todos los números ya son "generalmente" positivos, o si no desea resultados negativos.
Carl Smith
82

El siguiente código convertirá el valor decimal d en hexadecimal. También le permite agregar relleno al resultado hexadecimal. Entonces 0 se convertirá en 00 por defecto.

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
fuente
55
Esto no manejará adecuadamente los valores negativos. decimalToHex (-6, 4) devolvería 00-6.
JonMR
3
También tiene problemas con las carrozas, pero poner Math.round () solucionó eso. (+ 1ed)
Michael - ¿Dónde está Clay Shirky?
Estoy "sacando" números de una matriz ('255,0,55', etc.) y .toString (16) no funcionó. ¡Todo lo que obtuve fueron los mismos números! Agregué la función "Número" al frente, ¡y ahora funciona! ¡Solo pasé unas cuatro horas tratando de encontrar la solución!
Cristofayre
65
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
Baznr
fuente
1
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Lori
2
No es tan difícil extenderlo, está cortando los últimos dígitos con .slice (-number) allí. Si agrega más ceros al frente, funcionará bien.
Tatarize
19
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')😁
Ninh Pham
39

Para completar, si desea la representación hexadecimal del complemento a dos de un número negativo, puede usar el operador de desplazamiento de relleno cero a la derecha>>> . Por ejemplo:

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

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

Sin embargo, hay una limitación: los operadores de bits de JavaScript tratan sus operandos como una secuencia de 32 bits , es decir, obtienes el complemento de dos de 32 bits.

Alberto
fuente
2
esta es, con mucho, la respuesta más valiosa a esta pregunta :)
albertjan
Excavando todas las preguntas porque C# number to hexadecimalestaba produciendo resultados diferentes para Javascript number to hexadecimal. Parece que Javascript tiene el problema con los números negativos. Esta respuesta parece ser la solución al problema.
goamn
Esto fue enormemente útil, ¡gracias! Estaba usando esto para colores RGB, así que para obtener la variante de 24 bits, corte los dos primeros caracteres (el FF adicional)((-2)>>>0).toString(16).substring(2)
antonyh
36

Con acolchado:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
Fabio Ferrari
fuente
2
@Lucas Devuelve los últimos 4 caracteres.
Gabriel
19

Sin el bucle:

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

Además, ¿no es mejor no usar pruebas de bucle que deben evaluarse?

Por ejemplo, en lugar de:

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

tener

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

Combinando algunas de estas buenas ideas para una función de valor RGB a hexadecimal (agregue la #otra parte para 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
fuente
¡Gracias por esto! Mencioné dejar un comentario hace mucho tiempo. Fue la clave de mi respuesta. stackoverflow.com/questions/5560248/…
Pimp Trizkit
16

La respuesta aceptada no tuvo en cuenta los códigos hexadecimales devueltos de un solo dígito. Esto se ajusta fácilmente mediante:

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

y

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

    return a;
}

Creo que las respuestas anteriores han sido publicadas en numerosas ocasiones por otros de una forma u otra. Los envuelvo en una función toHex () así:

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);
    }
}

Tenga en cuenta que la expresión regular numérica proviene de más de 10 funciones útiles de expresión regular de JavaScript para mejorar la eficiencia de sus aplicaciones web .

Actualización: después de probar esto varias veces, encontré un error (comillas dobles en RegExp), así que lo solucioné. ¡SIN EMBARGO! Después de probar un poco y haber leído la publicación de almaz, me di cuenta de que no podía obtener números negativos para trabajar.

Además, leí un poco sobre esto y, dado que todos los números de JavaScript se almacenan como palabras de 64 bits, pase lo que pase, intenté modificar el código numHex para obtener la palabra de 64 bits. Pero resulta que no puedes hacer eso. Si coloca "3.14159265" COMO NÚMERO en una variable, todo lo que podrá obtener es el "3", porque la porción fraccional solo es accesible multiplicando el número por diez (IE: 10.0) repetidamente. O para decirlo de otra manera: el valor hexadecimal de 0xF hace que el valor de coma flotante se traduzca a un número entero antes de ser AND, lo que elimina todo lo que está detrás del punto. En lugar de tomar el valor como un todo (es decir: 3.14159265) y ANDing el punto flotante valor de contra el valor 0xF.

Entonces, lo mejor que puede hacer, en este caso, es convertir el 3.14159265 en una cadena y luego simplemente convertir la cadena. Debido a lo anterior, también facilita la conversión de números negativos porque el signo menos se convierte en 0x26 en el frente del valor.

Entonces, lo que hice fue determinar que la variable contiene un número, simplemente convertirlo en una cadena y convertir la cadena. Esto significa para todos que, en el lado del servidor, necesitará eliminar la cadena de entrada y luego determinar que la información entrante es numérica. Puede hacerlo fácilmente simplemente agregando un "#" al frente de los números y "A" al frente de una cadena de caracteres que regresa. Vea la función toHex ().

¡Que te diviertas!

Después de otro año y mucho pensar, decidí que la función "toHex" (y también tengo una función "fromHex") realmente necesitaba ser renovada. Toda la pregunta era "¿Cómo puedo hacer esto de manera más eficiente?" Decidí que una función hexadecimal to / from no debería importarle si algo es una parte fraccionaria, pero al mismo tiempo debería garantizar que las partes fraccionarias estén incluidas en la cadena.

Entonces la pregunta se convirtió en "¿Cómo sabes que estás trabajando con una cadena hexadecimal?". La respuesta es simple. Utilice la información estándar previa a la cadena que ya se reconoce en todo el mundo.

En otras palabras, use "0x". Entonces, mi función toHex mira para ver si eso ya está allí y si lo está, solo devuelve la cadena que se le envió. De lo contrario, convierte la cadena, el número, lo que sea. Aquí está la función 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;
}

Esta es una función muy rápida que tiene en cuenta dígitos individuales, números de coma flotante e incluso verifica si la persona está enviando un valor hexadecimal para que se vuelva a hechizar. Solo usa cuatro llamadas a funciones y solo dos de ellas están en el bucle. Para deshechar los valores que 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;
}

Al igual que la función toHex (), la función fromHex () primero busca el "0x" y luego traduce la información entrante en una cadena si aún no es una cadena. No sé cómo no sería una cadena, pero por las dudas, lo compruebo. Luego, la función se ejecuta, captura dos caracteres y los traduce a caracteres ASCII. Si desea que traduzca Unicode, deberá cambiar el bucle a cuatro (4) caracteres a la vez. Pero también debe asegurarse de que la cadena NO sea divisible por cuatro. Si es así, entonces es una cadena hexadecimal estándar. (Recuerde que la cadena tiene "0x" en la parte delantera).

Un script de prueba simple para mostrar que -3.14159265, cuando se convierte en una cadena, sigue siendo -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;

?>

Debido a cómo funciona JavaScript con respecto a la función toString (), se pueden eliminar todos esos problemas que antes causaban problemas. Ahora todas las cadenas y números se pueden convertir fácilmente. Además, cosas como los objetos provocarán un error generado por el propio JavaScript. Creo que esto es tan bueno como parece. La única mejora que queda es que W3C solo incluya una función toHex () y fromHex () en JavaScript.

Mark Manning
fuente
Creo que todavía tienes trabajo que hacer aquí ... if( s.substr(0,2)antes if (typeof s != "string")probablemente no sea lo que quieres, por ejemplo. Lo que había devuelto tampoco era lo que esperaba ( toHex(0x1f635)da "0x313238353635"). No he investigado más.
ruffin
Creo que eres incorrecto. Su ejemplo está usando una cadena hexadecimal que NO es una cadena, sino un número. Por lo tanto, el 1f635 saldría como está. Si hubiera puesto "0x1f635", habría resultado diferente. (es decir: la rutina acababa de devolver el número hexadecimal que había enviado a la rutina) :-)
Mark Manning
El primer punto fue que no puede usar substr& toLowerCaseen una sin cadena ... por lo tanto typeof, o bien debe llegar antes, o, si esperaba toHexlanzar una sin cadena allí, debe eliminar el typeofcheque por completo. ¿Tener sentido? Es decir, si usara el código aquí sin ediciones y llamara toHex(0x1f635), obtendría Uncaught TypeError: s.substr is not a function. Si muevo la cadena emitida antes, tienes razón, el número se convierte al decimal primero, tal vez, y las cosas van de lado. Lo que, por supuesto, significa que no puedes hacer un simple lanzamiento aquí si sno es una cadena.
ruffin
En realidad, bajo XP esto funciona bien. Ha habido una serie de actualizaciones de Javascript que están haciendo que Javascript sea encasillado. Lo que arrojaría una excepción. Bajo XP funciona jusr. Al menos para mi. En un mundo de conversión tipográfica, es apropiado poner "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}". Pero ox1f635 todavía no es una cadena. :-)
Mark Manning
12
var number = 3200;
var hexString = number.toString(16);

El 16 es la raíz y hay 16 valores en un número hexadecimal :-)

Danny Wilson
fuente
12

Para cualquier persona interesada, aquí hay un JSFiddle que compara la mayoría de las respuestas dadas a esta pregunta .

Y aquí está el método con el que terminé yendo:

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

Además, tenga en cuenta que si está buscando convertir de decimal a hexadecimal para usar en CSS como un tipo de datos de color , puede preferir extraer los valores RGB del decimal y usar rgb () .

Por ejemplo ( 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 + ')')

Esto establece #some-elementla colorpropiedad CSS de rgb(64, 62, 154).

Sombrero
fuente
10

Restringido / rellenado a un número establecido de caracteres:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
Adamarla
fuente
2
Esto convierte un número en una cadena hexadecimal Y rellena ceros a la izquierda, ¡es hermoso!
Gordon
10

Aquí hay una versión recortada de 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
fuente
En total desacuerdo con @HypersoftSystems, si su entorno o situación lo permite, entonces use ES6. No todos los scripts deben ejecutarse en intérpretes de bootleg heredados, también existe babel por alguna razón. Y, por último, ES6 es mucho más legible si lo sabes. Dicho esto, dar respuestas JS estándar podría ayudar a más personas, pero teniendo en cuenta que hay otras respuestas para versiones anteriores de JS, tener una respuesta ES6 solo es beneficioso, definitivamente no se requiere la queja "así es como lo hice en el día".
WiR3D
Las opiniones no hacen hechos, por lo tanto su "argumento" no es válido. @ WiR3D
Hypersoft Systems
@HypersoftSystems es tan válido como el suyo, si no más, ya que el suyo es tan obstinado y limita el contexto a un contexto que probablemente no sea válido en la mayoría de las aplicaciones modernas.
WiR3D el
error del usuario: "igual de obstinado", "probablemente" y "más".
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
}

fuente
1
+1 gracias! Cuando trabajas con CSS, toString (16) es importante para que obtengas resultados como FF0000
Tyler Egeto
77
cuando trabaje con css (o svg, que acepta especificaciones de color de estilo css) puede eludir todo el problema escribiendo color: rgb(r,g,b)donde rg y b son números decimales.
Telent
1
Debería 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

Si desea convertir un número a una representación hexadecimal de un valor de color RGBA, he encontrado que esta es la combinación más útil de varios consejos desde aquí:

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

El comentario AFAIK 57807 es incorrecto y debería ser algo así como: var hex = Number (d) .toString (16); en lugar 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
fuente
6

¿Y si el número es negativo?

Aquí está mi versión.

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
fuente
5

Estoy haciendo la conversión a una cadena hexadecimal en un bucle bastante grande, así que probé varias técnicas para encontrar la más rápida. Mis requisitos eran tener una cadena de longitud fija como resultado y codificar los valores negativos correctamente (-1 => ff..f).

Simple .toString(16)no funcionó para mí, ya que necesitaba valores negativos para codificar correctamente. El siguiente código es el más rápido que he probado hasta ahora en valores de 1-2 bytes (tenga en cuenta que symbolsdefine el número de símbolos de salida que desea obtener, es decir, para un entero de 4 bytes, debería 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;
}

Funciona más rápido que .toString(16)en números de 1-2 bytes y más lento en números más grandes (cuando symbols> = 6), pero aún así debe superar a los métodos que codifican los valores negativos correctamente.

almaz
fuente
5

Como dice la respuesta aceptada, la forma más fácil de convertir de decimal a hexadecimal es var hex = dec.toString(16). Sin embargo, es posible que prefiera agregar una conversión de cadena, ya que garantiza que las representaciones de cadena "12".toString(16)funcionen correctamente.

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

Para revertir el proceso, también puede usar la solución a continuación, ya que es aún más corta.

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

Parece ser más lento en Google Chrome y Firefox, pero es significativamente más rápido en Opera. Ver http://jsperf.com/hex-to-dec .

RD
fuente
5

Cómo convertir decimal a hexadecimal en JavaScript

No pude encontrar una conversión de decimal a hexadecimal brutalmente limpia / simple que no involucrara un desorden de funciones y matrices ... así que tuve que hacer esto por mí mismo.

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
fuente
55
Oh, mi ... esta es una forma realmente terrible y horrible de hacer esto, hecho en un estilo de codificación aún más feo. Honestamente: ¿qué hay de malo con los saltos de línea y la sangría? Variables de una letra? De Verdad?
Victor Schröder
1
Revisado ¿Es así de horrible? ¿Y el estilo es mejor? Originalmente pensé que sería más fácil de entender con cada paso "literalmente" deletreado así con letras ... a veces puedo ser bastante estúpido
JonLikeSquirrel
44
Lo siento, sí, sigue siendo terrible. Su código todavía usa muchos bucles ineficientes y está contaminando el espacio de nombres global, entre otros problemas. El enfoque en sí es excesivo para una tarea que se puede lograr con una simple llamada a la función. Si desea mejorar su estilo de codificación en JS, le recomiendo que lea material como w3.org/wiki/JavaScript_best_practices y google.github.io/styleguide/javascriptguide.xml . Solo google sobre el tema.
Victor Schröder
1
Hice una prueba de velocidad en Chrome y mi función de overkill es aproximadamente un 30% más rápida que .toString (16), mientras que en Firefox mi función es un 40% más lenta que .toString (16) ... Chrome demuestra que mis bucles excesivos son MÁS eficientes que la función nativa .toString (16) de los navegadores, mientras que Firefox demuestra por qué más personas prefieren Chrome. ¿O eso es al revés? ¡Un día Chrome puede incluso actualizarse a un .toString (16) más rápido, lo que me hace incorrecto en ambos casos! De cualquier manera, no estoy completamente equivocado, y no tienes toda la razón. Sin embargo, dejando a un lado mi ego, entiendo tu punto al menos el 30%. ;)
JonLikeSquirrel
2
Nunca tiene que declarar una serie de cadenas que contengan caracteres individuales cada una. Solo declara una cadena de caracteres. Puede obtener un carácter de una cadena tal como lo haría con una matriz, utilizando corchetes.
David Spector
3

Para resumir todo esto;

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;
}

Sin embargo, si no necesita convertirlo de nuevo a un número entero al final (es decir, para los colores), bastará con asegurarse de que los valores no sean negativos.

realkstrawn93
fuente
2

No he encontrado una respuesta clara, sin verificaciones si es negativa o positiva, que utiliza el complemento de dos (números negativos incluidos). Para eso, muestro mi solución a un byte:

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

Puede usar esta instrucción para cualquier número de bytes, solo que agrega FFen los lugares respectivos. Por ejemplo, a dos bytes:

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

Si desea convertir un entero de matriz en una cadena hexadecimal:

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

En caso de que desee convertir a una representación 'completa' de JavaScript o CSS, puede 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
fuente
2

Puede hacer algo como esto en ECMAScript 6 :

const toHex = num => (num).toString(16).toUpperCase();
Alireza
fuente
1

Si está buscando convertir números enteros grandes, es decir, números mayores que Number.MAX_SAFE_INTEGER - 9007199254740991, puede usar el siguiente código

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

Abhilash Nayak
fuente
1

Esto se basa en las soluciones de Prestaul y Tod. Sin embargo, esta es una generalización que explica el tamaño variable de una variable (por ejemplo, analizar el valor firmado de un registro serie del 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 prueba:

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)}`);
   }

Resultados de la prueba:

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: no estoy muy seguro de por qué falla por encima de 32 bits

Brian
fuente
-3

Aquí está mi solución:

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

La pregunta dice: "Cómo convertir decimal a hexadecimal en JavaScript" . Mientras que la pregunta no especifica que la cadena hexadecimal debe comenzar con un prefijo 0x, cualquiera que escriba código debe saber que 0x se agrega a los códigos hexadecimales para distinguir los códigos hexadecimales de los identificadores programáticos y otros números (1234 podría ser hexadecimal, decimal o incluso octal).

Por lo tanto, para responder correctamente a esta pregunta, con el fin de escribir guiones, debe agregar el prefijo 0x.

La función Math.abs (N) convierte los negativos en positivos, y como beneficio adicional, no parece que alguien lo haya pasado por una astilladora.

La respuesta que quería, habría tenido un especificador de ancho de campo, por lo que podríamos, por ejemplo, mostrar valores de 8/16/32/64 bits de la forma en que los vería en una aplicación de edición hexadecimal. Esa es la respuesta correcta real.

Sistemas Hypersoft
fuente
1
En la práctica de codificación general, cualquier secuencia alfanumérica que comience con una letra, NO ES UN NÚMERO. Por ejemplo: ABCDEF012345678 es un identificador válido en casi todos los lenguajes de codificación del planeta.
Hypersoft Systems
1
Ah, y el prefijo 0x no es un problema para JavaScript: Number('0xFF') === 255;para todos los que quieren la operación inversa.
Hypersoft Systems