Comment convertir décimal en hexadécimal en JavaScript

1479

Comment convertir des valeurs décimales en leur équivalent hexadécimal en JavaScript?

Luke Smith
la source
7
Juste un avertissement ici, c'est que vous commencez à partir d'une représentation de chaîne, il est très facile de perdre sa précision lorsque vous la transformez en nombre dans le cadre de la conversion en hexadécimal. Voir danvk.org/wp/2012-01-20/… .
studgeek
Cette fonction est exactement ce dont vous avez besoin
Mohammad Musavi

Réponses:

2476

Convertissez un nombre en une chaîne hexadécimale avec:

hexString = yourNumber.toString(16);

Et inversez le processus avec:

yourNumber = parseInt(hexString, 16);
Prestaul
la source
42
yourNum est une chaîne hexadécimale dans ce cas. Par exemple (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul
8
@forste, vous ne "perdrez pas de précision" si vous convertissez un nombre javascript (c'est-à-dire un objet Number, qui dans le script ECMA est un Double) en hexadécimal et inversement en utilisant cette technique. La question que vous avez liée fait spécifiquement référence à des nombres trop grands pour tenir dans un Double (d'où la représentation sous forme de chaîne dans la question). Si vous avez un numéro, cela fonctionnera. Si vous avez quelque chose de trop gros pour être un objet Number javascript (un Double), vous devrez trouver autre chose.
Prestaul
12
@Derek, j'ai un problème psychologique qui ne me permettra pas de tolérer des parenthèses inutiles ... @ tout le monde, yourNumberest une variable. Si vous souhaitez utiliser un littéral numérique, vous devrez faire quelque chose comme (45).toString(16), mais si vous codez en dur un nombre, veuillez simplement l'écrire vous-même sous forme de chaîne hexadécimale ... (45).toString(16)sera toujours égal '2d', alors ne gaspillez pas le processeur cycles pour comprendre cela.
Prestaul
21
@Prestaul "Ne gaspillez pas les cycles de CPU pour comprendre cela" - c'est ce qu'on appelle l'optimisation prématurée. À moins que le JavaScript ne fonctionne sur un 286, je doute que les frais généraux soient importants. De plus, '45' pourrait être un nombre magique que le programmeur doit être capable de reconnaître (comme la durée du timeout en secondes), tandis que '2d', eh bien qui va le reconnaître?
Dejay Clayton
47
Si vous n'aimez pas les parenthèses, vous pouvez simplement utiliser un point supplémentaire:42..toString(16)
Thomas Watson
142

Si vous devez gérer des choses comme les champs de bits ou les couleurs 32 bits, vous devez traiter les numéros signés. La fonction JavaScript toString(16)retournera un nombre hexadécimal négatif qui n'est généralement pas ce que vous voulez. Cette fonction fait un ajout fou pour en faire un nombre positif.

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
la source
5
est ce complément à deux?
Julian
2
Cette conversion n'est normalement pas nécessaire car JavaScript peut représenter tous les champs de bits 32 bits sous forme de nombres non signés (voir Number.MAX_SAFE_INTEGER). Pour la même raison, la conversion en non signé peut s'écrire:number = 0x100000000 + number;
Johannes Matokic
3
Une petite note sur mon commentaire précédent: alors que la représentation hexadécimale devrait fonctionner pour les nombres jusqu'à Number.MAX_SAFE_INTEGER, cela ne vaut pas pour les opérations au niveau du bit (qui sont souvent utilisées pour créer des couleurs 32 bits). Le résultat des opérations au niveau du bit est toujours un entier 32 bits signé. Par conséquent, les résultats au niveau du bit> = 2 ^ 31 sont négatifs et 0x100000000 | 0 === 0.
Johannes Matokic
25
Vous pouvez utiliser l' >>>opérateur pour convertir un nombre en représentation non signée, par exemple des ((-3253) >>> 0).toString(16)retours "fffff34b".
csharpfolk
1
+1pour un ajout utile, mais si vous convertissez des nombres dans une notation différente, tous les nombres sont déjà "généralement" positifs, sinon vous voulez des résultats négatifs.
Carl Smith
82

Le code ci-dessous convertira la valeur décimale d en hexadécimal. Il vous permet également d'ajouter un remplissage au résultat hexadécimal. Donc 0 deviendra 00 par défaut.

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
la source
5
Cela ne gérera pas correctement les valeurs négatives. decimalToHex (-6, 4) retournerait 00-6.
JonMR
3
Il a également des problèmes avec les flottants, mais la mise en Math.round () a corrigé cela. (+ 1ed)
Michael - Où est Clay Shirky
Je «tire» des nombres d'un tableau («255,0,55», etc.) et le .toString (16) n'a pas fonctionné. Je n'ai eu que les mêmes chiffres! J'ai ajouté la fonction "Numéro" à l'avant, et maintenant ça marche! J'ai seulement passé environ quatre heures à essayer de trouver la solution !!
Cristofayre
65
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
Baznr
la source
1
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Lori
2
Ce n'est pas si difficile de l'étendre, vous coupez les derniers chiffres avec .slice (-number) là-bas. Si vous ajoutez plus de zéros à l'avant, cela fonctionnera bien.
Tatarize le
19
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')😁
Ninh Pham
39

Pour être complet, si vous voulez la représentation hexadécimale en complément à deux d'un nombre négatif, vous pouvez utiliser l' opérateur de décalage vers la droite de remplissage nul>>> . Par exemple:

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

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

Il y a cependant une limitation: les opérateurs JavaScript au niveau du bit traitent leurs opérandes comme une séquence de 32 bits , c'est-à-dire que vous obtenez le complément à 32 bits.

Alberto
la source
2
c'est de loin la réponse la plus valable à cette question :)
albertjan
Creuser à travers toutes les questions car C# number to hexadecimalproduisait des résultats différents Javascript number to hexadecimal. Il semble que Javascript ait un problème avec les nombres négatifs. Cette réponse semble être la solution au problème.
goamn
C'était extrêmement utile, merci! J'utilisais cela pour les couleurs RVB, donc pour obtenir la variante 24 bits, couper les deux premiers caractères (extra FF) -((-2)>>>0).toString(16).substring(2)
antonyh
36

Avec rembourrage:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
Fabio Ferrari
la source
2
@Lucas Il retourne les 4 derniers caractères.
Gabriel
19

Sans boucle:

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

N'est-il pas préférable de ne pas utiliser de tests de boucle qui doivent être évalués?

Par exemple, au lieu de:

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

avoir

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

Combiner certaines de ces bonnes idées pour une fonction de valeur RVB en hexadécimal (ajoutez le #ailleurs pour 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
la source
Merci pour cela! Je ment pour laisser un commentaire il y a longtemps. C'était la clé de ma réponse. stackoverflow.com/questions/5560248/…
Pimp Trizkit
16

La réponse acceptée ne tenait pas compte des codes hexadécimaux renvoyés à un seul chiffre. Ceci est facilement ajusté par:

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

et

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

    return a;
}

Je crois que les réponses ci-dessus ont été publiées à plusieurs reprises par d'autres sous une forme ou une autre. Je les enveloppe dans une fonction toHex () comme ceci:

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

Notez que l'expression régulière numérique provient de plus de 10 fonctions d'expression régulière JavaScript utiles pour améliorer l'efficacité de vos applications Web .

Mise à jour: Après avoir testé cette chose plusieurs fois, j'ai trouvé une erreur (guillemets doubles dans le RegExp), j'ai donc corrigé cela. TOUTEFOIS! Après pas mal de tests et après avoir lu l'article par almaz - j'ai réalisé que je ne pouvais pas faire fonctionner les nombres négatifs.

De plus - j'ai fait un peu de lecture à ce sujet et puisque tous les numéros JavaScript sont stockés sous forme de mots 64 bits, peu importe quoi - j'ai essayé de modifier le code numHex pour obtenir le mot 64 bits. Mais il s'avère que vous ne pouvez pas faire ça. Si vous mettez "3.14159265" COMME UN NUMÉRO dans une variable - tout ce que vous pourrez obtenir est le "3", car la partie fractionnaire n'est accessible qu'en multipliant le nombre par dix (IE: 10.0) à plusieurs reprises. Ou pour le dire autrement - la valeur hexadécimale de 0xF entraîne la conversion de la valeur à virgule flottante en un entier avant qu'elle ne soit ANDée, ce qui supprime tout derrière la période. Plutôt que de prendre la valeur dans son ensemble (c.-à-d.: 3,14159265) et d'opérer la valeur à virgule flottante sur la valeur 0xF.

Donc, la meilleure chose à faire, dans ce cas, est de convertir le 3.14159265 en chaîne , puis de convertir simplement la chaîne. En raison de ce qui précède, il permet également de convertir facilement des nombres négatifs car le signe moins devient simplement 0x26 à l'avant de la valeur.

Donc, ce que j'ai fait était de déterminer que la variable contient un nombre - il suffit de le convertir en chaîne et de convertir la chaîne. Cela signifie pour tout le monde que du côté serveur, vous devrez décocher la chaîne entrante, puis déterminer que les informations entrantes sont numériques. Vous pouvez le faire facilement en ajoutant simplement un "#" au début des chiffres et un "A" au début d'une chaîne de caractères qui revient. Voir la fonction toHex ().

S'amuser!

Après une autre année et beaucoup de réflexion, j'ai décidé que la fonction "toHex" (et j'ai aussi une fonction "fromHex") avait vraiment besoin d'être remaniée. Toute la question était "Comment puis-je faire cela plus efficacement?" J'ai décidé qu'une fonction de / vers hexadécimal ne devrait pas se soucier si quelque chose est une partie fractionnaire, mais en même temps, elle devrait s'assurer que les parties fractionnaires sont incluses dans la chaîne.

Alors la question est devenue: "Comment savez-vous que vous travaillez avec une chaîne hexadécimale?". La réponse est simple. Utilisez les informations de pré-chaîne standard déjà reconnues dans le monde entier.

En d'autres termes - utilisez "0x". Alors maintenant, ma fonction toHex cherche à voir si c'est déjà là et si c'est le cas - elle retourne juste la chaîne qui lui a été envoyée. Sinon, il convertit la chaîne, le nombre, peu importe. Voici la fonction toHex révisée:

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

Il s'agit d'une fonction très rapide qui prend en compte les chiffres uniques, les nombres à virgule flottante et vérifie même si la personne envoie une valeur hexadécimale pour être à nouveau hexadécimée. Il utilise seulement quatre appels de fonction et seulement deux d'entre eux sont dans la boucle. Pour décocher les valeurs que vous utilisez:

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

Comme la fonction toHex (), la fonction fromHex () recherche d'abord le "0x" et ensuite elle traduit les informations entrantes en une chaîne si ce n'est pas déjà une chaîne. Je ne sais pas comment ce ne serait pas une chaîne - mais juste au cas où - je vérifie. La fonction passe ensuite en revue, saisissant deux caractères et les traduisant en caractères ASCII. Si vous voulez qu'il traduise Unicode, vous devrez changer la boucle en passant par quatre (4) caractères à la fois. Mais vous devez également vous assurer que la chaîne n'est PAS divisible par quatre. Si c'est le cas - alors c'est une chaîne hexadécimale standard. (N'oubliez pas que la chaîne comporte "0x" à l'avant.)

Un script de test simple pour montrer que -3.14159265, une fois converti en chaîne, est toujours -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;

?>

En raison de la façon dont JavaScript fonctionne en ce qui concerne la fonction toString (), tous ces problèmes peuvent être éliminés, ce qui causait auparavant des problèmes. Désormais, toutes les chaînes et tous les nombres peuvent être convertis facilement. De plus, des choses telles que des objets entraîneront la génération d'une erreur par JavaScript lui-même. Je crois que c'est à peu près aussi bon que possible. La seule amélioration qui reste est que le W3C inclue simplement une fonction toHex () et fromHex () dans JavaScript.

Mark Manning
la source
Je pense que vous avez encore du travail à faire ici ... if( s.substr(0,2)avant ce if (typeof s != "string")n'est probablement pas ce que vous voulez, par exemple. Ce que j'étais revenu n'était pas non plus ce que j'attendais ( toHex(0x1f635)donne "0x313238353635"). N'ont pas enquêté plus avant.
ruffin
Je crois que vous vous trompez. Votre exemple utilise une chaîne hexadécimale qui n'est PAS une chaîne, mais un nombre. Par conséquent, le 1f635 se présenterait tel quel. Si vous aviez mis "0x1f635", cela serait sorti différemment. (c'est-à-dire que la routine aurait juste retourné le numéro hexadécimal que vous avez envoyé à la routine.) :-)
Mark Manning
Le premier point était que vous ne pouvez pas utiliser substr& toLowerCasesur une non-chaîne ... donc soit les typeofbesoins doivent venir plus tôt, soit, si vous vous attendez toHexà lancer une non-chaîne là, vous devez supprimer typeofcomplètement la coche. Ça a du sens? Autrement dit, si j'utilisais le code ici sans modifications et toHex(0x1f635)que j'appelais, j'obtiendrais Uncaught TypeError: s.substr is not a function. Si je déplace la chaîne de caractères plus tôt, vous avez raison, le nombre est d'abord décimal, peut-être, et les choses vont de côté. Ce qui bien sûr signifie que vous ne pouvez pas faire un simple casting ici s'il sne s'agit pas d'une chaîne.
ruffin
En fait, sous XP, cela fonctionne très bien. Il y a eu un certain nombre de mises à jour de Javascript qui font que Javascript soit transtypé. Ce qui jetterait une exception. Sous XP, cela fonctionne. Au moins pour moi. Dans un monde de transtypage, mettre "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}" est approprié. Mais ox1f635 n'est toujours pas une chaîne. :-)
Mark Manning
12
var number = 3200;
var hexString = number.toString(16);

Le 16 est le radix et il y a 16 valeurs dans un nombre hexadécimal :-)

Danny Wilson
la source
12

Pour toute personne intéressée, voici un JSFiddle comparant la plupart des réponses données à cette question .

Et voici la méthode que j'ai utilisée:

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

En outre, gardez à l'esprit que si vous cherchez à convertir de la décimale en hexadécimal pour une utilisation en CSS en tant que type de données de couleur , vous préférerez plutôt extraire les valeurs RVB de la décimale et utiliser rgb () .

Par exemple ( 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 + ')')

Ceci définit #some-elementla colorpropriété CSS de rgb(64, 62, 154).

Chapeau
la source
10

Contraint / complété à un nombre défini de caractères:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
Adamarla
la source
2
Cela convertit un nombre en une chaîne hexadécimale ET des pads menant à des zéros, c'est magnifique!
Gordon
10

Voici une version réduite d'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
la source
En fort désaccord avec @HypersoftSystems, si votre environnement ou votre situation vous le permet, utilisez ES6. Tous les scripts ne doivent pas être exécutés dans des interpréteurs de bootleg hérités, Babel existe également pour une raison. Et enfin, ES6 est beaucoup plus lisible si vous le savez. Cela dit, donner des réponses JS standard pourrait aider plus de gens, mais étant donné qu'il existe d'autres réponses pour les anciennes versions de JS, avoir une réponse ES6 n'est que bénéfique, la diatribe "c'est comme ça que je l'ai fait dans la journée" n'est certainement pas nécessaire.
WiR3D
Les opinions ne font pas de faits, donc votre "argument" n'est pas valide. @ WiR3D
Hypersoft Systems
@HypersoftSystems est aussi valide que le vôtre, sinon plus, car le vôtre est tout aussi avisé et limite le contexte à un contexte probablement invalide dans la plupart des applications modernes.
WiR3D
erreur utilisateur: "tout comme l'opinion", "probablement" et "la plupart".
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
}

la source
1
+1 merci! Lorsque vous travaillez avec CSS, le toString (16) est important pour que vous obteniez des résultats comme FF0000
Tyler Egeto
7
lorsque vous travaillez avec css (ou svg, qui accepte les spécifications de couleurs de style css), vous pouvez contourner le problème en écrivant color: rgb(r,g,b)où rg et b sont des nombres décimaux.
telent
1
Devrait être: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 vous souhaitez convertir un nombre en une représentation hexadécimale d'une valeur de couleur RGBA, j'ai trouvé que c'était la combinaison la plus utile de plusieurs conseils à partir d'ici:

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

Le commentaire AFAIK 57807 est erroné et devrait ressembler à ceci : var hex = Number (d) .toString (16); au lieu 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
la source
6

Et si le nombre est négatif?

Voici ma version.

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
la source
5

Je fais la conversion en chaîne hexadécimale dans une boucle assez grande, j'ai donc essayé plusieurs techniques afin de trouver la plus rapide. Par conséquent, je devais avoir une chaîne de longueur fixe et encoder correctement les valeurs négatives (-1 => ff..f).

Simple .toString(16)n'a pas fonctionné pour moi car j'avais besoin de valeurs négatives pour être correctement encodées. Le code suivant est le plus rapide que j'ai testé jusqu'à présent sur des valeurs de 1 à 2 octets (notez que cela symbolsdéfinit le nombre de symboles de sortie que vous souhaitez obtenir, c'est-à-dire pour un entier de 4 octets, il doit être égal à 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;
}

Il fonctionne plus rapidement que .toString(16)sur des nombres de 1 à 2 octets et plus lentement sur des nombres plus grands (lorsque symbols> = 6), mais devrait toujours surpasser les méthodes qui codent correctement les valeurs négatives.

almaz
la source
5

Comme l'indique la réponse acceptée, le moyen le plus simple de convertir de décimal en hexadécimal est var hex = dec.toString(16). Cependant, vous préférerez peut-être ajouter une conversion de chaîne, car elle garantit que les représentations de chaîne comme "12".toString(16)fonctionnent correctement.

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

Pour inverser le processus, vous pouvez également utiliser la solution ci-dessous, car elle est encore plus courte.

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

Il semble être plus lent dans Google Chrome et Firefox, mais il est nettement plus rapide dans Opera. Voir http://jsperf.com/hex-to-dec .

RD
la source
5

Comment convertir décimal en hexadécimal en JavaScript

Je n'ai pas été en mesure de trouver une conversion décimale en hexadécimale brutalement propre / simple qui n'impliquait pas un désordre de fonctions et de tableaux ... j'ai donc dû faire cela pour moi.

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
la source
5
Oh mon ... c'est une façon vraiment terrible et horrible de le faire, fait dans un style de codage encore plus laid. Honnêtement: qu'est-ce qui ne va pas avec les sauts de ligne et l'indentation? Variables à lettre unique? Vraiment?
Victor Schröder
1
Révisé. Est-ce que c'est horrible? Et le style est-il meilleur ?? Je pensais à l'origine qu'il serait plus facile à comprendre à chaque étape "littéralement" énoncée comme ça avec des lettres ... parfois je peux être assez stupide
JonLikeSquirrel
4
Désolé, oui, toujours terrible. Votre code utilise toujours de nombreuses boucles inefficaces et pollue l'espace de noms global, entre autres. L'approche elle-même est exagérée pour une tâche qui peut être accomplie par un simple appel de fonction. Si vous souhaitez améliorer votre style de codage dans JS, je vous recommande fortement d'aller lire des documents tels que w3.org/wiki/JavaScript_best_practices et google.github.io/styleguide/javascriptguide.xml . Il suffit de google sur le sujet.
Victor Schröder
1
J'ai fait un test de vitesse dans Chrome et ma fonction Overkill est environ 30% plus rapide que .toString (16), alors que dans Firefox ma fonction est 40% plus lente que .toString (16) ... Chrome prouve que mes boucles excessives sont PLUS efficaces que la fonction native .toString (16) des navigateurs, tandis que Firefox prouve pourquoi plus de gens préfèrent Chrome. Ou est-ce à l'envers ?? Un jour, Chrome peut même passer à un .toString (16) plus rapide, ce qui me rend incorrect dans les deux cas! De toute façon, je ne me trompe pas complètement, et vous n'avez pas entièrement raison. Mon ego mis à part cependant, j'obtiens au moins 30% de votre point de vue. ;)
JonLikeSquirrel
2
Vous n'avez jamais besoin de déclarer un tableau de chaînes contenant chacune des caractères uniques. Déclarez simplement une chaîne de caractères. Vous pouvez obtenir un caractère d'une chaîne comme vous le feriez avec un tableau, en utilisant des crochets.
David Spector
3

Pour tout résumer;

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

Cependant, si vous n'avez pas besoin de le reconvertir en un entier à la fin (c'est-à-dire pour les couleurs), il suffit de vous assurer que les valeurs ne sont pas négatives.

realkstrawn93
la source
2

Je n'ai pas trouvé de réponse claire, sans vérification si elle est négative ou positive, qui utilise le complément à deux (nombres négatifs inclus). Pour cela, je montre ma solution à un octet:

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

Vous pouvez utiliser cette instruction pour n'importe quel nombre d'octets, seulement vous ajoutez FFdans les endroits respectifs. Par exemple, à deux octets:

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

Si vous souhaitez convertir un entier de tableau en chaîne hexadécimale:

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

Dans le cas où vous cherchez à convertir en une représentation JavaScript ou CSS «complète», vous pouvez utiliser quelque chose comme:

  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
la source
2

Vous pouvez faire quelque chose comme ça dans ECMAScript 6 :

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

Si vous cherchez à convertir de grands entiers, c'est-à-dire des nombres supérieurs à Number.MAX_SAFE_INTEGER - 9007199254740991, vous pouvez utiliser le code suivant

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

Abhilash Nayak
la source
1

Ceci est basé sur les solutions de Prestaul et Tod. Cependant, il s'agit d'une généralisation qui tient compte de la taille variable d'une variable (par exemple, analyser la valeur signée d'un journal série de microcontrôleur).

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 test:

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

Résultats de test:

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'

Remarque: Je ne sais pas trop pourquoi il échoue au-dessus de 32 bits

Brian
la source
-3

Voici ma solution:

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

La question dit: "Comment convertir décimal en hexadécimal en JavaScript" . Bien que la question ne spécifie pas que la chaîne hexadécimale doit commencer par un préfixe 0x, toute personne qui écrit du code doit savoir que 0x est ajouté aux codes hexadécimaux pour distinguer les codes hexadécimaux des identificateurs de programmation et d' autres nombres (1234 peut être hexadécimal, décimal ou même octal).

Par conséquent, pour répondre correctement à cette question, à des fins d'écriture de script, vous devez ajouter le préfixe 0x.

La fonction Math.abs (N) convertit les négatifs en positifs, et en prime, il ne semble pas que quelqu'un l'ait exécutée à travers une déchiqueteuse.

La réponse que je voulais, aurait eu un spécificateur de largeur de champ, donc nous pourrions par exemple afficher les valeurs 8/16/32/64 bits comme vous les verriez répertoriées dans une application d'édition hexadécimale. Voilà, c'est la vraie réponse.

Systèmes Hypersoft
la source
1
Dans la pratique générale du codage, toute séquence alphanumérique commençant par une lettre, N'EST PAS UN NUMÉRO. Par exemple: ABCDEF012345678 est un identifiant valide dans presque tous les langages de codage de la planète.
Hypersoft Systems
1
Oh, et le préfixe 0x n'est pas un problème pour javascript: Number('0xFF') === 255;pour tous ceux qui veulent l'opération inverse.
Hypersoft Systems