Jak przekonwertować liczbę dziesiętną na szesnastkową w JavaScript

1479

Jak przekonwertować wartości dziesiętne na ich szesnastkowy odpowiednik w JavaScript?

Luke Smith
źródło
7
Tylko ostrzeżenie tutaj, że zaczynasz od reprezentacji łańcucha, bardzo łatwo jest stracić precyzję, gdy zamienisz go na Liczbę w ramach konwersji na heks. Zobacz danvk.org/wp/2012-01-20/… .
studgeek
Ta funkcja jest dokładnie tym, czego potrzebujesz
Mohammad Musavi

Odpowiedzi:

2474

Konwertuj liczbę na ciąg szesnastkowy za pomocą:

hexString = yourNumber.toString(16);

I odwróć proces za pomocą:

yourNumber = parseInt(hexString, 16);
Prestaul
źródło
42
yourNum jest w tym przypadku łańcuchem szesnastkowym. Np. (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul
8
@forste, nie „stracisz precyzji”, jeśli przekonwertujesz numer javascript (tj. obiekt Number, który w skrypcie ECMA jest Double) na heksadecymalny iz powrotem za pomocą tej techniki. Pytanie, które podłączyłeś, odnosi się konkretnie do liczb zbyt dużych, aby zmieściły się w Double (stąd reprezentacja ciągu w pytaniu). Jeśli masz numer, to zadziała. Jeśli masz coś zbyt dużego, aby być obiektem javascript Number (Double), musisz znaleźć coś innego.
Prestaul
12
@Derek, mam problem psychologiczny, który nie pozwoli mi tolerować niepotrzebnych nawiasów ... @ wszyscy inni yourNumbersą zmiennymi. Jeśli chcesz użyć literału numerycznego, musisz zrobić coś takiego (45).toString(16), ale jeśli zapisujesz cyfrę na sztywno, po prostu napisz ją jako ciąg szesnastkowy ... (45).toString(16)zawsze będzie równy '2d', więc nie marnuj procesora cykle, aby to rozgryźć.
Prestaul
21
@ Prestaul „Nie marnuj cykli procesora, żeby to rozgryźć” - to się nazywa przedwczesna optymalizacja. O ile JavaScript nie działa na 286, wątpię, czy narzut ma znaczenie. Ponadto „45” może być magiczną liczbą, którą programista musi rozpoznać (np. Czas oczekiwania w sekundach), podczas gdy „2d”, no cóż, kto to rozpozna?
Dejay Clayton
47
Jeśli nie lubisz nawiasów, możesz użyć dodatkowej kropki:42..toString(16)
Thomas Watson
142

Jeśli potrzebujesz obsługiwać pola bitowe lub kolory 32-bitowe, musisz radzić sobie z podpisanymi liczbami. Funkcja JavaScript toString(16)zwróci ujemną liczbę szesnastkową, która zwykle nie jest tym, czego chcesz. Ta funkcja ma jakiś szalony dodatek, dzięki czemu jest liczbą dodatnią.

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
źródło
5
czy to uzupełnienie dwóch?
Julian
2
Ta konwersja zwykle nie jest potrzebna, ponieważ JavaScript może reprezentować wszystkie 32-bitowe pola jako liczby bez znaku (patrz Number.MAX_SAFE_INTEGER). Z tego samego powodu konwersję na niepodpisaną można zapisać jako:number = 0x100000000 + number;
Johannes Matokic
3
Krótka uwaga na temat mojego poprzedniego komentarza: Podczas gdy reprezentacja szesnastkowa powinna działać dla liczb do Number.MAX_SAFE_INTEGER, nie dotyczy to operacji bitowych (które są często używane do tworzenia kolorów 32-bitowych). Wynikiem operacji bitowych jest zawsze 32-bitowa liczba całkowita ze znakiem. Dlatego wyniki bitowe> = 2 ^ 31 są ujemne i 0x100000000 | 0 === 0.
Johannes Matokic
25
Za pomocą >>>operatora można przekonwertować liczbę na reprezentację bez znaku, np . ((-3253) >>> 0).toString(16)Zwroty "fffff34b".
csharpfolk
1
+1przydatny dodatek, ale jeśli konwertujesz liczby na inną notację, wszystkie liczby są już „zwykle” dodatnie, lub chcesz wyniki ujemne.
Carl Smith,
82

Poniższy kod konwertuje wartość dziesiętną d na szesnastkową. Pozwala także dodać dopełnienie do wyniku szesnastkowego. Tak więc 0 będzie domyślnie 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
źródło
5
To nie będzie poprawnie obsługiwać wartości ujemnych. decimalToHex (-6, 4) zwróci 00-6.
JonMR
3
Ma także problemy z pływakami, ale naprawienie tego spowodowało użycie Math.round (). (+ 1ed)
Michael - Where's Clay Shirky
„Wyciągam” liczby z tablicy („255,0,55” itp.) I .toString (16) nie działa. Otrzymałem tylko te same liczby! Z przodu dodałem funkcję „Numer”, a teraz działa! Spędziłem tylko około czterech godzin próbując znaleźć rozwiązanie !!
Cristofayre
65
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
Baznr
źródło
1
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Lori,
2
Nie jest to trudne do rozszerzenia, odcinasz ostatnie cyfry za pomocą .slice (-number). Jeśli dodasz więcej zer do przodu, będzie działać dobrze.
Tatarize
19
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')😁
Ninh Pham
39

Aby uzyskać kompletność, jeśli chcesz dwójkową reprezentację szesnastkową uzupełnienia liczby ujemnej, możesz użyć operatora przesunięcia zera i wypełnienia w prawo>>> . Na przykład:

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

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

Jest jednak jedno ograniczenie: operatory bitowe JavaScript traktują swoje operandy jako sekwencję 32 bitów , co oznacza, że ​​otrzymujemy uzupełnienie 32-bitowe dwa.

Alberto
źródło
2
to zdecydowanie najcenniejsza odpowiedź na to pytanie :)
albertjan
Przekopując się przez wszystkie pytania, ponieważ C# number to hexadecimalprzynosiłem inne wyniki niż Javascript number to hexadecimal. Wygląda na to, że JavaScript ma problem z liczbami ujemnymi. Ta odpowiedź wydaje się być rozwiązaniem problemu.
bramka
To było bardzo pomocne, dziękuję! ((-2)>>>0).toString(16).substring(2)
Używałem
36

Z wyściółką:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
Fabio Ferrari
źródło
2
@Lucas Zwraca ostatnie 4 znaki.
Gabriel,
19

Bez pętli:

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

Czy nie lepiej też nie używać testów pętli, które należy ocenić?

Na przykład zamiast:

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

mieć

for (var i = 0, var j = hex.length; i < j; i++){}
mystifeid
źródło
19

Łącząc niektóre z tych dobrych pomysłów na funkcję RGB-wartość-szesnastkową (dodaj #gdzie indziej dla 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
źródło
Dzięki za to! Zamierzam zostawić komentarz dawno temu. To był klucz do mojej odpowiedzi. stackoverflow.com/questions/5560248/…
Pimp Trizkit
16

Przyjęta odpowiedź nie uwzględniała zwracanych jednocyfrowych kodów szesnastkowych. Można to łatwo regulować poprzez:

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

i

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

    return a;
}

Uważam, że powyższe odpowiedzi zostały opublikowane wiele razy przez innych w takiej czy innej formie. Zawijam je w funkcję toHex () w następujący sposób:

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

Pamiętaj, że liczbowe wyrażenie regularne pochodzi z ponad 10 przydatnych funkcji wyrażeń regularnych JavaScript, które poprawiają wydajność twoich aplikacji internetowych .

Aktualizacja: Po kilkukrotnym przetestowaniu tej rzeczy znalazłem błąd (podwójne cudzysłowy w RegExp), więc to naprawiłem. JEDNAK! Po kilku testach i przeczytaniu posta przez almaz - zdałem sobie sprawę, że nie mogę uzyskać liczb ujemnych do działania.

Co więcej - przeczytałem o tym i ponieważ wszystkie numery JavaScript są przechowywane jako 64-bitowe słowa bez względu na wszystko - próbowałem zmodyfikować kod numHex, aby uzyskać 64-bitowe słowo. Ale okazuje się, że nie możesz tego zrobić. Jeśli wstawisz „3.14159265” JAKO NUMER do zmiennej - wszystko, co będziesz w stanie uzyskać, to „3”, ponieważ część ułamkowa jest dostępna tylko poprzez wielokrotne pomnożenie liczby przez dziesięć (IE: 10.0). Innymi słowy - wartość szesnastkowa 0xF powoduje, że wartość zmiennoprzecinkowa jest tłumaczona na liczbę całkowitą przed dodaniem AND, co usuwa wszystko poza kropką. Zamiast brać wartość jako całość (tj. 3,14159265) i ANDing zmiennoprzecinkowy wartość z wartością 0xf.

Najlepszą rzeczą do zrobienia w tym przypadku jest konwersja 3.14159265 na łańcuch, a następnie po prostu konwersja łańcucha. Z tego powodu ułatwia także konwersję liczb ujemnych, ponieważ znak minus po prostu staje się 0x26 z przodu wartości.

Więc postanowiłem, że zmienna zawiera liczbę - wystarczy przekonwertować ją na ciąg znaków i przekonwertować ciąg. Oznacza to dla wszystkich, że po stronie serwera będzie trzeba odznaczyć przychodzący ciąg, a następnie ustalić, czy przychodzące informacje są numeryczne. Możesz to łatwo zrobić, dodając „#” na początku liczb i „A” na początku powracającego ciągu znaków. Zobacz funkcję toHex ().

Baw się dobrze!

Po kolejnym roku i długich przemyśleniach zdecydowałem, że funkcja „toHex” (i mam również funkcję „fromHex”) naprawdę wymaga zmiany. Całe pytanie brzmiało: „Jak mogę to zrobić bardziej wydajnie?” Zdecydowałem, że funkcja szesnastkowa do / z nie powinna dbać o to, czy coś jest częścią ułamkową, ale jednocześnie powinna upewnić się, że części ułamkowe są zawarte w ciągu.

Więc pytanie brzmiało: „Skąd wiesz, że pracujesz z łańcuchem szesnastkowym?”. Odpowiedź jest prosta. Użyj standardowych informacji wstępnych, które są już rozpoznawane na całym świecie.

Innymi słowy - użyj „0x”. Więc teraz moja funkcja toHex sprawdza, czy już tam jest, a jeśli tak - po prostu zwraca ciąg, który został do niej wysłany. W przeciwnym razie konwertuje ciąg, liczbę, cokolwiek. Oto poprawiona funkcja toHex:

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

Jest to bardzo szybka funkcja, która bierze pod uwagę pojedyncze cyfry, liczby zmiennoprzecinkowe, a nawet sprawdza, czy dana osoba wysyła wartość szesnastkową, aby ponownie została przekreślona. Używa tylko czterech wywołań funkcji i tylko dwa z nich są w pętli. Aby cofnąć heksowanie używanych wartości:

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

Podobnie jak funkcja toHex (), funkcja fromHex () najpierw szuka „0x”, a następnie tłumaczy przychodzące informacje na ciąg, jeśli nie jest to już ciąg. Nie wiem, jak by to nie był sznurek - ale na wszelki wypadek - sprawdzam. Następnie funkcja przechodzi, przechwytuje dwa znaki i tłumaczy je na znaki ASCII. Jeśli chcesz, aby tłumaczył Unicode, musisz zmienić pętlę na cztery (4) znaki jednocześnie. Ale musisz także upewnić się, że łańcuch NIE jest podzielny przez cztery. Jeśli tak, to jest to standardowy ciąg szesnastkowy. (Pamiętaj, że ciąg ma z przodu „0x”).

Prosty skrypt testowy pokazujący, że -3,14159265, po przekonwertowaniu na ciąg znaków, ma nadal wartość -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;

?>

Ze względu na to, jak JavaScript działa w odniesieniu do funkcji toString (), wszystkie te problemy można wyeliminować, które wcześniej powodowały problemy. Teraz wszystkie ciągi i liczby można łatwo przekonwertować. Co więcej, takie obiekty jak obiekty powodują błąd generowany przez sam JavaScript. Uważam, że jest to tak dobre, jak to możliwe. Jedyne ulepszenie, jakie pozostało, to włączenie przez W3C funkcji toHex () i fromHex () w JavaScript.

Mark Manning
źródło
Myślę, że jeszcze dużo pracy do zrobienia ... if( s.substr(0,2)przed if (typeof s != "string")prawdopodobnie nie jest to, co chcesz, na przykład. To, co wróciłem, nie było tym, czego się spodziewałem ( toHex(0x1f635)daje "0x313238353635"). Nie badałem dalej.
ruffin
Uważam, że się mylisz. W twoim przykładzie użyto ciągu szesnastkowego, który NIE jest ciągiem, ale liczbą. Dlatego 1f635 wyszedłby tak, jak jest. Gdybyś wstawił „0x1f635”, wyszedłoby to inaczej. (tzn .: procedura zwróciłaby właśnie numer szesnastkowy, który wysłałeś do procedury.) :-)
Mark Manning,
Pierwszą kwestią było to, że nie możesz użyć substr& toLowerCasena non-string ... więc albo typeoftrzeba przyjść wcześniej, albo, jeśli spodziewałeś toHexsię rzucić non-string tutaj, powinieneś typeofcałkowicie usunąć czek. Ma sens? To znaczy, gdybym użył kodu tutaj bez edycji i zadzwonił toHex(0x1f635), dostałbym Uncaught TypeError: s.substr is not a function. Jeśli przesunę rzut rzutu wcześniej, masz rację, być może liczba najpierw rzuci się na dziesiętną i wszystko pójdzie na boki. Co oczywiście oznacza, że ​​nie można tu wykonać prostej obsady, jeśli snie jest to struna.
ruffin
Właściwie pod XP to działa dobrze. Wprowadzono wiele aktualizacji Javascript, które powodują, że Javascript jest typecast. Który rzuciłby wyjątek. Pod XP działa jusr. Przynajmniej dla mnie. W świecie typecast - właściwe jest wstawienie „if (typeof s ==” string ”&& s.substr (0,2) ==„ 0x ”) {return s;}”. Ale ox1f635 wciąż nie jest ciągiem. :-)
Mark Manning,
12
var number = 3200;
var hexString = number.toString(16);

16 to podstawa, a liczba szesnastkowa zawiera 16 wartości :-)

Danny Wilson
źródło
12

Dla wszystkich zainteresowanych, oto JSFiddle porównujący większość odpowiedzi udzielonych na to pytanie .

A oto metoda, którą ostatecznie wybrałem:

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

Należy również pamiętać, że jeśli chcesz przekonwertować z dziesiętnego na szesnastkowy w celu użycia w CSS jako typu danych koloru , możesz zamiast tego wolić wyodrębnić wartości RGB z dziesiętnej i użyć rgb () .

Na przykład ( 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 + ')')

Ustawia właściwość #some-elementCSS colorna rgb(64, 62, 154).

Kapelusz
źródło
10

Ograniczone / uzupełnione do określonej liczby znaków:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
Adamarla
źródło
2
To zamienia liczbę na ciąg szesnastkowy ORAZ wstawia wiodące zera, to jest piękne!
Gordon,
10

Oto skrócona wersja 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
źródło
Jeśli nie zgadzasz się z @HypersoftSystems, jeśli pozwala na to Twoje środowisko lub sytuacja, użyj ES6. Nie każdy skrypt musi działać w starszych interpretatorach bootlegów, również z jakiegoś powodu istnieje babel. I na koniec, ES6 jest znacznie bardziej czytelny, jeśli go znasz. To powiedziawszy, udzielanie standardowych odpowiedzi JS mogłoby pomóc większej liczbie osób, ale biorąc pod uwagę, że istnieją inne odpowiedzi dla starszych wersji JS, posiadanie odpowiedzi ES6 jest tylko korzystne, „zalecenie„ tak to zrobiłem w ciągu dnia ”zdecydowanie nie jest wymagane.
WiR3D,
Opinie nie przedstawiają faktów, dlatego twój „argument” jest nieważny. @ WiR3D
Hypersoft Systems
@HypersoftSystems jest tak samo ważny jak twój, jeśli nie bardziej, ponieważ twój jest tak samo opiniotwórczy i ogranicza kontekst do kontekstu, który prawdopodobnie jest nieprawidłowy w większości nowoczesnych aplikacji.
WiR3D
błąd użytkownika: „tak jak opinia”, „prawdopodobnie” i „większość”.
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
}

źródło
1
+1 dzięki! Podczas pracy z CSS ważna jest funkcja toString (16), dzięki czemu uzyskuje się wyniki takie jak FF0000
Tyler Egeto
7
podczas pracy z css (lub svg, który akceptuje specyfikacje kolorów w stylu css), możesz ominąć cały problem, pisząc, color: rgb(r,g,b)gdzie rg i b są liczbami dziesiętnymi.
telent
1
Powinno być: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

Jeśli chcesz przekonwertować liczbę na szesnastkową reprezentację wartości koloru RGBA, to jest to najbardziej przydatna kombinacja kilku wskazówek stąd:

function toHexString(n) {
    if(n < 0) {
        n = 0xFFFFFFFF + n + 1;
    }
    return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}
korona
źródło
8

Komentarz AFAIK 57807 jest niepoprawny i powinien wyglądać następująco: var hex = Number (d) .toString (16); zamiast 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
źródło
6

A jeśli liczba jest ujemna?

Oto moja wersja.

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
źródło
5

Robię konwersję na ciąg szesnastkowy w dość dużej pętli, więc wypróbowałem kilka technik, aby znaleźć najszybszą. W rezultacie moje wymagania miały mieć ciąg o stałej długości i poprawnie kodować wartości ujemne (-1 => ff..f).

Prosty .toString(16) nie działało dla mnie, ponieważ potrzebowałem poprawnie zakodowanych wartości ujemnych. Poniższy kod jest najszybszym, jaki do tej pory testowałem na wartościach 1-2 bajtowych (zwróć uwagę, że symbolsokreśla liczbę symboli wyjściowych, które chcesz uzyskać, to znaczy dla 4-bajtowej liczby całkowitej powinien wynosić 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;
}

Działa szybciej niż .toString(16)na liczbach 1-2 bajtowych i wolniej na większych liczbach (gdy symbols> = 6), ale nadal powinien przewyższać metody, które poprawnie kodują wartości ujemne.

Almaz
źródło
5

Zgodnie z przyjętą odpowiedzią najłatwiejszym sposobem konwersji z dziesiętnego na szesnastkowy jest var hex = dec.toString(16). Możesz jednak dodać konwersję ciągów, ponieważ zapewnia to, że takie reprezentacje ciągów "12".toString(16)działają poprawnie.

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

Aby odwrócić proces, możesz również skorzystać z poniższego rozwiązania, ponieważ jest ono jeszcze krótsze.

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

Wydaje się być wolniejszy w Google Chrome i Firefox, ale w Operze jest znacznie szybszy. Zobacz http://jsperf.com/hex-to-dec .

R & D
źródło
5

Jak przekonwertować liczbę dziesiętną na szesnastkową w JavaScript

Nie byłem w stanie znaleźć brutalnie czystej / prostej konwersji dziesiętnej na szesnastkową, która nie wymagałaby bałaganu funkcji i tablic ... więc musiałem to zrobić dla siebie.

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
źródło
5
O rany ... to naprawdę okropny, okropny sposób robienia tego, nawet w jeszcze brzydszym stylu kodowania. Szczerze mówiąc: co jest złego w łamaniu linii i wcięciach? Zmienne jednoliterowe? Naprawdę?
Victor Schröder,
1
Poprawiłem to. Czy to jest okropne? A czy styl jest lepszy? Początkowo myślałem, że łatwiej będzie zrozumieć z każdym krokiem „dosłownie” tak napisanym literami ... czasami mogę być całkiem głupi
JonLikeSquirrel
4
Przepraszam, tak, nadal okropne. Twój kod nadal używa wielu nieefektywnych pętli i zanieczyszcza między innymi globalną przestrzeń nazw. Samo podejście to przesada w stosunku do zadania, które można wykonać za pomocą prostego wywołania funkcji. Jeśli chcesz poprawić swój styl kodowania w JS, zdecydowanie zalecamy przeczytanie materiałów takich jak w3.org/wiki/JavaScript_best_practices i google.github.io/styleguide/javascriptguide.xml . Po prostu google na ten temat.
Victor Schröder,
1
Zrobiłem test prędkości w Chrome, a moja funkcja przepełnienia jest około 30% szybsza niż .toString (16), podczas gdy w Firefox moja funkcja jest o 40% wolniejsza niż .toString (16) ... Chrome udowadnia, że ​​moje nadmierne pętle są WIĘCEJ wydajne niż natywna funkcja przeglądarki .toString (16), a Firefox udowadnia, dlaczego więcej osób woli Chrome. A może to wstecz? Pewnego dnia Chrome może nawet zaktualizować do szybszej wersji .toString (16), co czyni mnie niepoprawnym w obu przypadkach! Tak czy inaczej, nie jestem całkowicie w błędzie, a ty nie do końca masz rację. Odkładając na bok moje ego, rozumiem o co najmniej 30%. ;)
JonLikeSquirrel
2
Nie musisz nigdy deklarować tablicy ciągów zawierających pojedyncze znaki. Po prostu zadeklaruj ciąg znaków. Możesz uzyskać znak z ciągu znaków, tak jak w przypadku tablicy, używając nawiasów kwadratowych.
David Spector,
3

Podsumowując wszystko;

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

Jeśli jednak nie musisz konwertować go z powrotem na liczbę całkowitą (np. W przypadku kolorów), wystarczy upewnić się, że wartości nie są ujemne.

realkstrawn93
źródło
2

Nie znalazłem jasnej odpowiedzi, bez sprawdzenia, czy jest ona negatywna czy pozytywna, która używa uzupełnienia do dwóch (włączając liczby ujemne). W tym celu pokazuję moje rozwiązanie jednobajtowemu:

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

Możesz użyć tej instrukcji do dowolnej liczby bajtów, tylko dodajesz FFw odpowiednich miejscach. Na przykład do dwóch bajtów:

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

Jeśli chcesz rzutować liczbę całkowitą tablicy na ciąg szesnastkowy:

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

Jeśli chcesz przekonwertować na „pełną” reprezentację JavaScript lub CSS, możesz użyć czegoś takiego:

  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
źródło
2

Możesz zrobić coś takiego w ECMAScript 6 :

const toHex = num => (num).toString(16).toUpperCase();
Alireza
źródło
1

Jeśli chcesz przekonwertować duże liczby całkowite, tzn. Liczby większe niż liczba.MAX_SAFE_INTEGER - 9007199254740991, możesz użyć następującego kodu

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

Abhilash Nayak
źródło
1

Jest to oparte na rozwiązaniach Prestaul i Tod. Jest to jednak uogólnienie uwzględniające zmienny rozmiar zmiennej (np. Parsing podpisana wartość z dziennika szeregowego mikrokontrolera).

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

Skrypt testowy:

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

Wyniki testów:

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'

Uwaga: Nie jestem pewien, dlaczego zawodzi powyżej 32-bitowego rozmiaru

Brian
źródło
-3

Oto moje rozwiązanie:

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

Pytanie brzmi: „Jak przekonwertować dziesiętne na szesnastkowe w JavaScript” . Chociaż pytanie nie określa, że ​​ciąg szesnastkowy powinien zaczynać się od przedrostka 0x, każdy, kto pisze kod, powinien wiedzieć, że 0x jest dodawany do kodów szesnastkowych w celu odróżnienia kodów szesnastkowych od identyfikatorów programowych i innych liczb (1234 może być szesnastkowy, dziesiętny lub nawet ósemkowy).

Dlatego, aby poprawnie odpowiedzieć na to pytanie, w celu pisania skryptów, musisz dodać przedrostek 0x.

Funkcja Math.abs (N) konwertuje negatywy na pozytywy, a jako bonus nie wygląda na to, że ktoś przejechał go przez rębak.

Odpowiedź, której potrzebowałem, miałaby specyfikator szerokości pola, dzięki czemu moglibyśmy na przykład pokazywać wartości 8/16/32/64-bitowe w sposób, w jaki widziałbyś je na liście w aplikacji do edycji szesnastkowej. To jest właściwa, prawidłowa odpowiedź.

Hypersoft Systems
źródło
1
W ogólnej praktyce kodowania każda sekwencja alfanumeryczna rozpoczynająca się na literę NIE JEST NUMEREM. Na przykład: ABCDEF012345678 jest poprawnym identyfikatorem w prawie każdym języku kodowania na świecie.
Hypersoft Systems,
1
Aha, a przedrostek 0x nie stanowi problemu dla javascript: Number('0xFF') === 255;dla wszystkich, którzy chcą operacji odwrotnej.
Hypersoft Systems,