Konvertieren von Dezimalzahlen in Hexadezimalzahlen in JavaScript

1479

Wie konvertiert man Dezimalwerte in JavaScript in ihre hexadezimale Entsprechung?

Luke Smith
quelle
7
Nur eine Warnung hier, dass Sie von einer Zeichenfolgendarstellung ausgehen. Es ist sehr leicht, die Genauigkeit zu verlieren, wenn Sie sie im Rahmen der Konvertierung in Hex in Zahl umwandeln. Siehe danvk.org/wp/2012-01-20/… .
Studgeek
Diese Funktion ist genau das, was Sie brauchen
Mohammad Musavi

Antworten:

2474

Konvertieren Sie eine Zahl in eine hexadezimale Zeichenfolge mit:

hexString = yourNumber.toString(16);

Und kehren Sie den Prozess um mit:

yourNumber = parseInt(hexString, 16);
Prestaul
quelle
42
yourNum ist in diesem Fall eine Hex-Zeichenfolge. ZB (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul
8
@forste, Sie verlieren nicht an Präzision, wenn Sie eine Javascript-Nummer (dh ein Number-Objekt, das im ECMA-Skript ein Double ist) mit dieser Technik in hex und zurück konvertieren. Die von Ihnen verknüpfte Frage bezieht sich speziell auf Zahlen, die zu groß sind, um in ein Double zu passen (daher die Zeichenfolgendarstellung in der Frage). Wenn Sie eine Nummer haben, funktioniert dies. Wenn Sie etwas haben, das zu groß ist, um ein Javascript-Zahlenobjekt (ein Double) zu sein, müssen Sie etwas anderes finden.
Prestaul
12
@Derek, ich habe ein psychologisches Problem, das es mir nicht erlaubt, unnötige Klammern zu tolerieren ... @ Jeder andere yourNumberist eine Variable. Wenn Sie ein numerisches Literal verwenden möchten, müssen Sie so etwas tun (45).toString(16), aber wenn Sie eine Zahl hart codieren, schreiben Sie sie bitte selbst als Hex-Zeichenfolge ... (45).toString(16)wird immer gleich sein '2d', verschwenden Sie also keine CPU Zyklen, um das herauszufinden.
Prestaul
21
@Prestaul "Verschwenden Sie keine CPU-Zyklen, um das herauszufinden" - das nennt man vorzeitige Optimierung. Wenn das JavaScript nicht auf einem 286 ausgeführt wird, bezweifle ich, dass der Overhead von Bedeutung ist. Darüber hinaus könnte '45' eine magische Zahl sein, die der Programmierer erkennen muss (z. B. die Zeitüberschreitungsdauer in Sekunden), während '2d', wer wird das erkennen?
Dejay Clayton
47
Wenn Sie die Klammern nicht mögen, können Sie einfach einen zusätzlichen Punkt verwenden:42..toString(16)
Thomas Watson
142

Wenn Sie mit Bitfeldern oder 32-Bit-Farben umgehen müssen, müssen Sie sich mit vorzeichenbehafteten Zahlen befassen. Die JavaScript-FunktiontoString(16) gibt eine negative Hexadezimalzahl zurück, die normalerweise nicht Ihren Wünschen entspricht. Diese Funktion macht eine verrückte Addition, um daraus eine positive Zahl zu machen.

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
quelle
5
ist das die Ergänzung von zwei?
Julian
2
Diese Konvertierung wird normalerweise nicht benötigt, da JavaScript alle 32-Bit-Bitfelder als vorzeichenlose Zahlen darstellen kann (siehe Number.MAX_SAFE_INTEGER). Aus dem gleichen Grund kann die Umwandlung in unsigniert wie number = 0x100000000 + number;
folgt
3
Ein kurzer Hinweis zu meinem vorherigen Kommentar: Während die Hex-Darstellung für Zahlen bis Number.MAX_SAFE_INTEGER funktionieren sollte, gilt dies nicht für bitweise Operationen (die häufig zum Erstellen von 32-Bit-Farben verwendet werden). Das Ergebnis bitweiser Operationen ist immer eine vorzeichenbehaftete 32-Bit-Ganzzahl. Daher sind bitweise Ergebnisse> = 2 ^ 31 negativ und 0x100000000 | 0 === 0.
Johannes Matokic
25
Sie können den >>>Operator verwenden, um Zahlen in vorzeichenlose Darstellungen umzuwandeln, z . B. ((-3253) >>> 0).toString(16)Rückgaben "fffff34b".
Csharpfolk
1
+1Für eine nützliche Ergänzung, aber wenn Sie Zahlen in eine andere Notation konvertieren, sind alle Zahlen "normalerweise" bereits positiv, oder Sie möchten negative Ergebnisse.
Carl Smith
82

Der folgende Code konvertiert den Dezimalwert d in hexadezimal. Außerdem können Sie dem hexadezimalen Ergebnis eine Auffüllung hinzufügen. Aus 0 wird also standardmäßig 00.

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
quelle
5
Dies behandelt negative Werte nicht richtig. decimalToHex (-6, 4) würde 00-6 zurückgeben.
JonMR
3
Es gibt auch Probleme mit Floats, aber das Einfügen von Math.round () hat das behoben. (+ 1ed)
Michael - Wo ist Clay Shirky
Ich "ziehe" Zahlen aus einem Array ('255,0,55' usw.) und der .toString (16) hat nicht funktioniert. Ich habe nur die gleichen Zahlen bekommen! Ich habe die "Number" -Funktion vorne hinzugefügt und jetzt funktioniert es! Ich habe nur ungefähr vier Stunden damit verbracht, die Lösung zu finden !!
Cristofayre
65
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
Baznr
quelle
1
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Lori
2
Es ist nicht so schwer, es zu erweitern, Sie schneiden die letzten Ziffern mit .slice (-number) dort ab. Wenn Sie der Vorderseite weitere Nullen hinzufügen, funktioniert dies einwandfrei.
Tatarize
19
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')Nin
Ninh Pham
39

Für Vollständigkeit, wenn Sie das wollen Zweierkomplement- hexadezimale Darstellung einer negativen Zahl, können Sie das verwenden Null-Füll-Verschiebung nach rechts >>>Operator . Zum Beispiel:

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

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

Es gibt jedoch eine Einschränkung: Bitweise JavaScript-Operatoren behandeln ihre Operanden als eine Folge von 32 Bit , dh Sie erhalten das 32-Bit-Zweierkomplement.

Alberto
quelle
2
Dies ist bei weitem die wertvollste Antwort auf diese Frage :)
Albertjan
Durch alle Fragen zu graben, weil C# number to hexadecimales zu unterschiedlichen Ergebnissen kam Javascript number to hexadecimal. Es sieht so aus, als hätte Javascript das Problem mit negativen Zahlen. Diese Antwort scheint die Lösung des Problems zu sein.
Goamn
Das war sehr hilfreich, danke! Ich habe dies für RGB-Farben verwendet, um die 24-Bit-Variante zu erhalten, hacken Sie die ersten beiden Zeichen (das zusätzliche FF) -((-2)>>>0).toString(16).substring(2)
antonyh
36

Mit Polsterung:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
Fabio Ferrari
quelle
2
@Lucas Gibt die letzten 4 Zeichen zurück.
Gabriel
19

Ohne die Schleife:

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

Ist es auch nicht besser, keine Schleifentests zu verwenden, die ausgewertet werden müssen?

Zum Beispiel anstelle von:

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

haben

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

Kombinieren Sie einige dieser guten Ideen für eine RGB-Wert-zu-Hexadezimal-Funktion (fügen Sie die #andere für HTML / CSS hinzu):

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
quelle
Danke dafür! Ich möchte vor langer Zeit einen Kommentar abgeben. Es war der Schlüssel für meine Antwort. stackoverflow.com/questions/5560248/…
Pimp Trizkit
16

Die akzeptierte Antwort berücksichtigte keine einstelligen Hexadezimalcodes. Dies lässt sich leicht einstellen durch:

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

und

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

    return a;
}

Ich glaube, die obigen Antworten wurden mehrfach von anderen in der einen oder anderen Form veröffentlicht. Ich verpacke diese in eine toHex () - Funktion wie folgt:

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

Beachten Sie, dass der numerische reguläre Ausdruck aus 10+ nützlichen Funktionen für reguläre JavaScript-Ausdrücke stammt, um die Effizienz Ihrer Webanwendungen zu verbessern .

Update: Nachdem ich dieses Ding mehrmals getestet hatte, fand ich einen Fehler (doppelte Anführungszeichen in RegExp), also habe ich das behoben. JEDOCH! Nachdem ich einige Tests durchgeführt und den Beitrag von almaz gelesen hatte, wurde mir klar, dass ich keine negativen Zahlen zum Laufen bringen konnte.

Weiter - ich habe etwas darüber gelesen und da alle JavaScript-Nummern als 64-Bit-Wörter gespeichert sind, habe ich versucht, den numHex-Code zu ändern, um das 64-Bit-Wort zu erhalten. Aber es stellt sich heraus, dass Sie das nicht können. Wenn Sie "3.14159265" ALS NUMMER in eine Variable eingeben, erhalten Sie nur die "3", da auf den Bruchteil nur zugegriffen werden kann, indem Sie die Zahl wiederholt mit zehn (IE: 10.0) multiplizieren. Oder anders ausgedrückt: Der Hexadezimalwert von 0xF bewirkt, dass der Gleitkommawert in eine Ganzzahl übersetzt wird, bevor er UND-verknüpft wird, wodurch alles hinter der Periode entfernt wird. Anstatt den Wert als Ganzes zu nehmen (dh: 3.14159265) und den Gleitkomma UND zu verknüpfen gegen den 0xF-Wert UND zu verknüpfen.

In diesem Fall ist es am besten, den 3.14159265 in einen String umzuwandeln und dann einfach den String zu konvertieren. Aus diesem Grund ist es auch einfach, negative Zahlen umzuwandeln, da das Minuszeichen auf der Vorderseite des Werts nur 0x26 wird.

Ich habe also festgestellt, dass die Variable eine Zahl enthält - konvertieren Sie sie einfach in eine Zeichenfolge und konvertieren Sie die Zeichenfolge. Dies bedeutet für alle, dass Sie auf der Serverseite die eingehende Zeichenfolge entfernen und dann feststellen müssen, dass die eingehenden Informationen numerisch sind. Sie können dies einfach tun, indem Sie einfach ein "#" an die Vorderseite der Zahlen und ein "A" an die Vorderseite einer Zeichenfolge einfügen, die zurückkommt. Siehe die Funktion toHex ().

Habe Spaß!

Nach einem weiteren Jahr und viel Nachdenken entschied ich, dass die "toHex" -Funktion (und ich habe auch eine "fromHex" -Funktion) wirklich überarbeitet werden musste. Die ganze Frage war: "Wie kann ich das effizienter machen?" Ich entschied, dass eine to / from-Hexadezimalfunktion sich nicht darum kümmern sollte, ob etwas ein Bruchteil ist, aber gleichzeitig sicherstellen sollte, dass Bruchteile in der Zeichenfolge enthalten sind.

Dann stellte sich die Frage: "Woher wissen Sie, dass Sie mit einer hexadezimalen Zeichenfolge arbeiten?". Die Antwort ist einfach. Verwenden Sie die Standardinformationen vor der Zeichenfolge, die weltweit bereits anerkannt sind.

Mit anderen Worten - verwenden Sie "0x". Meine toHex-Funktion prüft nun, ob dies bereits vorhanden ist und ob dies der Fall ist. Sie gibt nur die Zeichenfolge zurück, die an sie gesendet wurde. Andernfalls wird die Zeichenfolge, die Nummer usw. konvertiert. Hier ist die überarbeitete toHex-Funktion:

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

Dies ist eine sehr schnelle Funktion, die einzelne Ziffern, Gleitkommazahlen und sogar prüft, ob die Person einen Hex-Wert sendet, um ihn erneut zu hexen. Es werden nur vier Funktionsaufrufe verwendet, von denen sich nur zwei in der Schleife befinden. So entsperren Sie die verwendeten Werte:

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

Wie die Funktion toHex () sucht die Funktion fromHex () zuerst nach "0x" und übersetzt dann die eingehenden Informationen in eine Zeichenfolge, wenn es sich nicht bereits um eine Zeichenfolge handelt. Ich weiß nicht, wie es kein String wäre - aber nur für den Fall - ich überprüfe. Die Funktion geht dann durch, greift nach zwei Zeichen und übersetzt diese in ASCII-Zeichen. Wenn Sie möchten, dass Unicode übersetzt wird, müssen Sie die Schleife so ändern, dass sie jeweils vier (4) Zeichen umfasst. Dann müssen Sie aber auch sicherstellen, dass die Zeichenfolge NICHT durch vier teilbar ist. Wenn ja, dann ist es eine hexadezimale Standardzeichenfolge. (Denken Sie daran, dass die Zeichenfolge vorne "0x" hat.)

Ein einfaches Testskript, das zeigt, dass -3.14159265 bei der Konvertierung in eine Zeichenfolge immer noch -3.14159265 ist.

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

?>

Aufgrund der Funktionsweise von JavaScript in Bezug auf die Funktion toString () können alle Probleme behoben werden, die zuvor Probleme verursacht haben. Jetzt können alle Zeichenfolgen und Zahlen einfach konvertiert werden. Darüber hinaus verursachen Objekte wie Objekte einen Fehler, der von JavaScript selbst generiert wird. Ich glaube, das ist ungefähr so ​​gut wie es nur geht. Die einzige verbleibende Verbesserung besteht darin, dass W3C nur die Funktionen toHex () und fromHex () in JavaScript enthält.

Mark Manning
quelle
Ich denke, Sie haben hier noch Arbeit zu erledigen ... if( s.substr(0,2)bevor es zum Beispiel if (typeof s != "string")wahrscheinlich nicht das ist, was Sie wollen. Was ich zurückgegeben hatte, war auch nicht das, was ich erwartet hatte ( toHex(0x1f635)gibt "0x313238353635"). Habe nicht weiter untersucht.
Ruffin
Ich glaube du bist falsch. In Ihrem Beispiel wird eine Hex-Zeichenfolge verwendet, die KEINE Zeichenfolge ist, sondern eine Zahl. Daher würde der 1f635 so herauskommen, wie er ist. Wenn Sie "0x1f635" eingegeben hätten, wäre es anders herausgekommen. (dh: Die Routine hätte gerade die Hex-Nummer zurückgegeben, die Sie an die Routine gesendet hatten.) :-)
Mark Manning
Der erste Punkt war, dass Sie substr& nicht toLowerCasefür eine Nicht-Zeichenfolge verwenden können. Entweder müssen die typeofAnforderungen früher gestellt werden, oder wenn Sie erwartet haben toHex, genau dort eine Nicht-Zeichenfolge zu verwenden, sollten Sie den typeofScheck vollständig entfernen . Sinn ergeben? Das heißt, wenn ich den Code hier ohne Änderungen verwenden und anrufen toHex(0x1f635)würde, würde ich bekommen Uncaught TypeError: s.substr is not a function. Wenn ich die Zeichenfolge früher verschiebe, haben Sie Recht, die Zahl wird möglicherweise zuerst auf Dezimalzahl umgewandelt, und die Dinge gehen seitwärts. Was natürlich bedeutet, dass Sie hier keine einfache Besetzung machen können, wenn ses sich nicht um eine Zeichenfolge handelt.
Ruffin
Unter XP funktioniert das eigentlich einwandfrei. Es gab eine Reihe von Aktualisierungen von Javascript, die dazu führen, dass Javascript typisiert wird. Welches würde eine Ausnahme werfen. Unter XP funktioniert es nur. Zumindest für mich. In einer typisierten Welt ist das Setzen von "if (typeof s ==" string "&& s.strstr (0,2) ==" 0x ") {return s;}" angemessen. Aber ox1f635 ist immer noch kein String. :-)
Mark Manning
12
var number = 3200;
var hexString = number.toString(16);

Die 16 ist der Radix und es gibt 16 Werte in einer Hexadezimalzahl :-)

Danny Wilson
quelle
12

Für alle Interessierten gibt es hier eine JSFiddle, die die meisten Antworten auf diese Frage vergleicht .

Und hier ist die Methode, mit der ich am Ende angefangen habe:

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

Auch bedenken , dass , wenn Sie schauen aus Dezimalzahl in hex zur Verwendung in CSS als konvertieren Farbe Datentyp , können Sie stattdessen lieber die RGB - Werte aus dem Dezimalsystem und Verwendung extrahieren rgb () .

Zum Beispiel ( 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 + ')')

Dies setzt #some-elementdie CSS- colorEigenschaft aufrgb(64, 62, 154) .

Hut
quelle
10

Auf eine festgelegte Anzahl von Zeichen beschränkt / aufgefüllt:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
Adamarla
quelle
2
Dies konvertiert eine Zahl in eine Zeichenfolge hex UND Pads führen Nullen, das ist schön!
Gordon
10

Hier ist eine abgespeckte ECMAScript 6-Version:

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
quelle
Verwenden Sie in starker Uneinigkeit mit @HypersoftSystems ES6, wenn Ihre Umgebung oder Situation dies zulässt. Nicht jedes Skript muss in älteren Bootleg-Interpreten ausgeführt werden, auch Babel existiert aus einem bestimmten Grund. Und schließlich ist ES6 viel besser lesbar, wenn Sie es wissen. Das heißt, Standard-JS-Antworten zu geben, könnte mehr Menschen helfen, aber da es andere Antworten für ältere JS-Versionen gibt, ist eine ES6-Antwort nur von Vorteil. Die Aufforderung "So habe ich es damals gemacht" ist definitiv nicht erforderlich.
WiR3D
Meinungen machen keine Fakten, daher ist Ihr "Argument" ungültig. @ WiR3D
Hypersoft Systems
@HypersoftSystems ist genauso gültig wie deins, wenn nicht mehr, da deins genauso einschätzend ist und den Kontext auf einen Kontext beschränkt, der in den meisten modernen Anwendungen wahrscheinlich ungültig ist.
WiR3D
Benutzerfehler: "genauso wie meinungsbildend", "wahrscheinlich" und "am meisten".
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
}

quelle
1
+1 danke! Bei der Arbeit mit CSS ist der toString (16) wichtig, damit Sie Ergebnisse wie FF0000
Tyler Egeto
7
Wenn Sie mit CSS arbeiten (oder mit SVG, das Farbspezifikationen im CSS-Stil akzeptiert), können Sie das gesamte Problem umgehen, indem Sie schreiben, color: rgb(r,g,b)wobei rg und b Dezimalzahlen sind.
Telent
1
Sollte sein: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

Wenn Sie eine Zahl in eine hexadezimale Darstellung eines RGBA-Farbwerts konvertieren möchten, ist dies die nützlichste Kombination mehrerer Tipps von hier:

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

AFAIK- Kommentar 57807 ist falsch und sollte ungefähr so lauten: var hex = Number (d) .toString (16); anstelle von 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
quelle
6

Und wenn die Zahl negativ ist?

Hier ist meine 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
quelle
5

Ich konvertiere in eine ziemlich große Schleife in einen Hex-String, also habe ich verschiedene Techniken ausprobiert, um die schnellste zu finden. Meine Anforderungen waren, eine Zeichenfolge fester Länge zu haben und negative Werte richtig zu codieren (-1 => ff..f).

Simple .toString(16)hat bei mir nicht funktioniert, da ich negative Werte brauchte, um richtig codiert zu werden. Der folgende Code ist der schnellste, den ich bisher mit 1-2-Byte-Werten getestet habe (Hinweis, symbolsder die Anzahl der Ausgabesymbole definiert, die Sie erhalten möchten, dh für eine 4-Byte-Ganzzahl sollte er gleich 8 sein):

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

Es ist schneller als .toString(16)bei 1-2-Byte-Zahlen und langsamer bei größeren Zahlen (wenn symbols> = 6), sollte jedoch Methoden übertreffen, die negative Werte richtig codieren.

Almaz
quelle
5

Wie in der akzeptierten Antwort angegeben, ist die Konvertierung von dezimal nach hexadezimal am einfachsten var hex = dec.toString(16). Möglicherweise möchten Sie jedoch lieber eine Zeichenfolgenkonvertierung hinzufügen, da dadurch sichergestellt wird, dass Zeichenfolgendarstellungen wie "12".toString(16)korrekt funktionieren.

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

Um den Vorgang umzukehren, können Sie auch die folgende Lösung verwenden, da diese noch kürzer ist.

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

In Google Chrome und Firefox scheint es langsamer zu sein, in Opera jedoch deutlich schneller. Siehe http://jsperf.com/hex-to-dec .

RD
quelle
5

Konvertieren von Dezimalzahlen in Hexadezimalzahlen in JavaScript

Ich war nicht in der Lage, eine brutal saubere / einfache Konvertierung von Dezimal zu Hexadezimal zu finden, die keine Unordnung von Funktionen und Arrays beinhaltete ... also musste ich dies für mich selbst machen.

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
quelle
5
Oh mein Gott ... das ist eine wirklich schreckliche, schreckliche Art, dies zu tun, in einem noch hässlicheren Codierungsstil. Ehrlich gesagt: Was ist los mit Zeilenumbrüchen und Einrückungen? Einzelbuchstabenvariablen? "Ja wirklich?"
Victor Schröder
1
Überarbeitet es. Ist das schrecklich? Und ist der Stil besser? Ich dachte ursprünglich, es wäre einfacher zu verstehen, wenn jeder einzelne Schritt "buchstäblich" so mit Buchstaben geschrieben wird ... manchmal kann ich ziemlich dumm sein
JonLikeSquirrel
4
Entschuldigung, ja, immer noch schrecklich. Ihr Code verwendet immer noch viele ineffiziente Schleifen und verschmutzt unter anderem den globalen Namespace. Der Ansatz selbst ist übertrieben für eine Aufgabe, die durch einen einfachen Funktionsaufruf ausgeführt werden kann. Wenn Sie Ihren Codierungsstil in JS verbessern möchten, empfehle ich dringend, Material wie w3.org/wiki/JavaScript_best_practices und google.github.io/styleguide/javascriptguide.xml zu lesen . Google einfach über das Thema.
Victor Schröder
1
Ich habe einen Geschwindigkeitstest in Chrome durchgeführt und meine Overkill-Funktion ist ungefähr 30% schneller als .toString (16), während meine Funktion in Firefox 40% langsamer ist als .toString (16) ... Chrome beweist, dass meine übermäßigen Schleifen effizienter sind als die native .toString (16) -Funktion des Browsers, während Firefox beweist, warum mehr Menschen Chrome bevorzugen. Oder ist das rückwärts? Eines Tages wird Chrome möglicherweise sogar auf ein schnelleres .toString (16) aktualisiert, was mich in beiden Fällen falsch macht! So oder so irre ich mich nicht ganz und du hast nicht ganz recht. Abgesehen von meinem Ego verstehe ich mindestens 30% davon. ;)
JonLikeSquirrel
2
Sie müssen niemals ein Array von Zeichenfolgen deklarieren, die jeweils einzelne Zeichen enthalten. Deklarieren Sie einfach eine Zeichenfolge. Sie können ein Zeichen aus einer Zeichenfolge wie mit einem Array abrufen, indem Sie eckige Klammern verwenden.
David Spector
3

Um alles zusammenzufassen;

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

Wenn Sie es jedoch am Ende nicht wieder in eine Ganzzahl konvertieren müssen (dh für Farben), sollte es ausreichen, nur sicherzustellen, dass die Werte nicht negativ sind.

realkstrawn93
quelle
2

Ich habe keine klare Antwort gefunden, ohne zu prüfen, ob sie negativ oder positiv ist und das Zweierkomplement verwendet (einschließlich negativer Zahlen). Dafür zeige ich meine Lösung auf ein Byte:

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

Sie können diese Anweisung für eine beliebige Anzahl von Bytes verwenden, die Sie nur FFan den entsprechenden Stellen hinzufügen . Zum Beispiel auf zwei Bytes:

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

Wenn Sie eine Array-Ganzzahl in eine hexadezimale Zeichenfolge umwandeln möchten:

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

Wenn Sie in eine 'vollständige' JavaScript- oder CSS-Darstellung konvertieren möchten, können Sie Folgendes verwenden:

  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
quelle
2

In ECMAScript 6 können Sie Folgendes tun :

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

Wenn Sie große Ganzzahlen konvertieren möchten, dh Zahlen größer als Number.MAX_SAFE_INTEGER - 9007199254740991, können Sie den folgenden Code verwenden

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

Abhilash Nayak
quelle
1

Dies basiert auf den Lösungen von Prestaul und Tod. Dies ist jedoch eine Verallgemeinerung, die die unterschiedliche Größe einer Variablen berücksichtigt (z. B. Analysieren des vorzeichenbehafteten Werts aus einem seriellen Protokoll eines Mikrocontrollers).

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

Testskript:

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

Testergebnisse:

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'

Hinweis: Nicht sicher, warum es über 32 Bit Größe fehlschlägt

Brian
quelle
-3

Hier ist meine Lösung:

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

Die Frage lautet: "Wie konvertiere ich Dezimal in Hexadezimal in JavaScript" . Während die Frage nicht angibt, dass die hexadezimale Zeichenfolge mit einem 0x-Präfix beginnen soll, sollte jeder, der Code schreibt, wissen, dass hexadezimalen Codes 0x hinzugefügt wird, um hexadezimale Codes von programmatischen Bezeichnern und anderen Zahlen zu unterscheiden (1234 kann hexadezimal, dezimal oder sein) sogar oktal).

Um diese Frage richtig zu beantworten, müssen Sie zum Schreiben von Skripten das Präfix 0x hinzufügen.

Die Math.abs (N) -Funktion wandelt Negative in Positive um, und als Bonus sieht es nicht so aus, als hätte jemand sie durch einen Holzhacker laufen lassen.

Die Antwort, die ich wollte, hätte einen Feldbreitenspezifizierer gehabt, so dass wir beispielsweise 8/16/32/64-Bit-Werte so anzeigen könnten, wie Sie sie in einer hexadezimalen Bearbeitungsanwendung sehen würden. Das ist die eigentliche, richtige Antwort.

Hypersoft-Systeme
quelle
1
In der allgemeinen Codierungspraxis ist jede alphanumerische Sequenz, die mit einem Buchstaben beginnt, KEINE NUMMER. Zum Beispiel: ABCDEF012345678 ist eine gültige Kennung in fast jeder Codierungssprache auf dem Planeten.
Hypersoft Systems
1
Oh, und das 0x-Präfix ist kein Problem für Javascript: Number('0xFF') === 255;für alle Leute da draußen, die die umgekehrte Operation wollen.
Hypersoft Systems