Как преобразовать десятичное в шестнадцатеричное в JavaScript?

1265

Как вы преобразовываете десятичные значения в их шестнадцатеричный эквивалент в JavaScript?

  • 7
    Просто предупреждение, что вы начинаете со строкового представления, очень легко потерять точность, когда вы превращаете его в число как часть преобразования его в шестнадцатеричное. См. Danvk.org/wp/2012-01-20/… .
  • 0
    Эта функция именно то, что вам нужно
Теги:
number-formatting
hex
base
tostring

26 ответов

2136
Лучший ответ

Преобразуйте число в шестнадцатеричную строку с помощью:

hexString = yourNumber.toString(16);
if (hexString.length % 2) {
  hexString = '0' + hexString;
}

и обратный процесс с:

yourNumber = parseInt(hexString, 16);
  • 1
    не так ли yourNum = parseInt (yourNum, 10); - а не 16?
  • 31
    yourNum - это шестнадцатеричная строка в этом случае. Например (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Показать ещё 21 комментарий
124

Если вам нужно обрабатывать такие вещи, как битовые поля или 32-битные цвета, то вам нужно иметь дело со знаковыми числами. Функция javascript toString(16) будет возвращать отрицательное шестнадцатеричное число, которое обычно не то, что вы хотите. Эта функция делает какое-то безумное дополнение, чтобы сделать ее положительным числом.

function decimalToHexString(number)
{
  if (number < 0)
  {
    number = 0xFFFFFFFF + number + 1;
  }

  return number.toString(16).toUpperCase();
}

console.log(decimalToHexString(27));
console.log(decimalToHexString(48.6));
  • 4
    это дополнение двух?
  • 1
    Это преобразование обычно не требуется, поскольку JavaScript может представлять все 32-разрядные битовые поля в виде чисел без знака (см. Number.MAX_SAFE_INTEGER). По той же причине преобразование в неподписанное может быть записано как: number = 0x100000000 + number;
Показать ещё 3 комментария
71

Нижеприведенный код преобразует десятичное значение d в шестнадцатеричное. Он также позволяет добавлять дополнение к шестнадцатеричному результату. поэтому 0 по умолчанию станет 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;
}
  • 3
    Это не будет правильно обрабатывать отрицательные значения. decimalToHex (-6, 4) вернет 00-6.
  • 1
    У него также есть проблемы с плавающей точкой, но исправление Math.round () исправило это. (+ 1ed)
53
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
  • 10
    Это или что-то вроде этого должно быть принятым ответом. В 99% случаев вам не нужны шестнадцатеричные строки переменной длины!
  • 1
    Это абсолютно не должно быть принятым ответом. 1. Это противный однострочник, который чрезвычайно трудно читать. Вызывает много ненужных умственных накладных расходов. 2. Его попытка гарантировать, что шестнадцатеричные строки не переменной длины бессмысленны и работают только в том случае, если ваше число соответствует одному байту (что, IMO, редко).
Показать ещё 2 комментария
31

С дополнением:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
  • 0
    Как именно .substr(-4) работает здесь?
  • 1
    @Lucas Возвращает последние 4 символа.
28

Для завершения, если вы хотите два-дополнение в шестнадцатеричном представлении отрицательного числа, вы можете используйте оператор zero-fill-right shift >>>. Например:

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

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

Однако существует одно ограничение: Поразрядные операторы javascript обрабатывают свои операнды как последовательность из 32 бит, то есть вы получаете 32-битное дополнение к двум.

  • 0
    это, безусловно, самый ценный ответ на этот вопрос :)
16

Без цикла:

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

Также не лучше ли использовать тесты цикла, которые должны быть оценены например, вместо:

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

есть

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

Сочетание некоторых из этих хороших идей для функции rgb to hex (добавьте # в другое место для 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);
}
  • 0
    Спасибо за это! Я хочу оставить комментарий давно. Это был ключ к моему ответу. stackoverflow.com/questions/5560248/...
  • 0
    Это отличный вспомогательный метод, спасибо, что поделились
12

В принятом ответе не учитывались шестнадцатеричные коды с шестью шестью символами. Это легко отрегулировать с помощью:

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

и

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

      return a;
   }

Я считаю, что вышеупомянутые ответы были неоднократно опубликованы другими в той или иной форме. Я обертываю их в функцию toHex() следующим образом:

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

Обратите внимание, что числовое регулярное выражение получено из 10+ полезных функций регулярного выражения JavaScript для повышения эффективности веб-приложений.

Обновление: после проверки этой вещи несколько раз я обнаружил ошибку (двойные кавычки в RegExp), поэтому я исправил это. ОДНАКО! После довольно много тестирования и прочтения сообщения от almaz - я понял, что не могу заставить отрицательные числа работать. Далее - я прочитал об этом, и поскольку все номера Javascript хранятся как 64-битные слова, независимо от того, что я пытался изменить код numHex, чтобы получить 64-битное слово. Но, оказывается, вы не можете этого сделать. Если вы поместите "3.14159265" КАК ЧИСЛО в переменную - все, что вы сможете получить, это "3", потому что дробная часть доступна только путем умножения числа на десять (IE: 10.0) несколько раз. Или, чтобы поместить этот другой путь - значение HEX 0xf заставляет значение FLOATING POINT быть переведено в INTEGER до того, как оно AND, которое удаляет все за период. Вместо того, чтобы принимать значение в целом (т.е.: 3.14159265) и ИСПРАВИТЬ значение FLOATING POINT против значения 0xf. Поэтому лучше всего сделать в этом случае преобразование 3.14159265 в STRING, а затем просто преобразовать строку. Из-за вышеизложенного он также упрощает преобразование отрицательных чисел, потому что знак минуса просто становится 0x26 в начале значения. Так что я сделал, это определить, что переменная содержит число - просто преобразуйте его в строку и преобразуйте строку. Что это означает для всех, так это то, что на стороне сервера вам нужно будет отключить входящую строку, а затем определить входящую информацию - числовую. Вы можете сделать это легко, просто добавив "#" к передней части номеров и "A" к фронту строки символов, возвращающейся назад. См. Функцию toHex().

Удачи!

После еще одного года и много размышлений я решил, что функция "toHex" (и у меня также есть функция fromHex) действительно нуждается в обновлении. Весь вопрос: "Как я могу сделать это более эффективно?" Я решил, что функция to/from hex не должна заботиться о том, является ли что-то дробной частью, но в то же время она должна гарантировать, что дробные части включены в строку. Тогда возник вопрос: "Откуда вы знаете, что работаете с шестнадцатеричной строкой?". Ответ прост. Используйте стандартную информацию перед строкой, которая уже признана во всем мире. Другими словами - используйте "0x" . Итак, теперь моя функция toHex смотрит, будет ли она уже там, и если она есть - она ​​просто возвращает строку, которая была отправлена ​​ему. В противном случае он преобразует строку, число, что угодно. Вот пересмотренная функция 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;
}

Это очень быстрая функция, которая учитывает отдельные цифры, числа с плавающей запятой и даже проверки, чтобы узнать, отправляет ли человек шестнадцатеричное значение для повторного использования. Он использует только четыре вызова функций, и только два из них находятся в цикле. Чтобы разблокировать значения, которые вы используете:

/////////////////////////////////////////////////////////////////////////////
//  fromHex().  Convert a hex string to ascii text.
/////////////////////////////////////////////////////////////////////////////
fromHex(s)
{
    var start = 0;
    var o = "";

    if( s.substr(0,2) == "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;
}

Как и функция toHex(), функция fromHex() сначала ищет "0x" , а затем переводит входящую информацию в строку, если она еще не является строкой. Я не знаю, как это будет не строка, но на всякий случай - я проверяю. Затем функция проходит, захватывая два символа и переводя их в символы ascii. Если вы хотите, чтобы он переводил юникод, вам нужно будет изменить цикл на четыре (4) символа за раз. Но тогда вам также необходимо убедиться, что строка НЕ ​​делится на четыре. Если это так, то это стандартная шестнадцатеричная строка. (Помните, что строка имеет "0x" на передней панели.)

Простой тест script, чтобы показать, что -3.14159265, преобразованный в строку, по-прежнему -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;

?>

Из-за того, как работает Javascript в отношении функции toString(), все эти проблемы могут быть устранены, что раньше вызывало проблемы. Теперь все строки и числа могут быть легко преобразованы. Кроме того, такие вещи, как объекты, будут вызывать ошибки, которые могут быть вызваны Javascript. Я считаю, что это так же хорошо, как и получается. Единственное улучшение - это то, что W3C просто включает функцию toHex() и fromHex() в Javascript.

  • 0
    Я думаю, что у вас все еще есть работа, которую нужно сделать здесь ... if( s.substr(0,2) раньше, if (typeof s != "string") вероятно, не то, что вы хотите, например. То, что я возвратил не то, что я ожидал ( toHex(0x1f635) дает "0x313238353635" ). Не исследовал дальше.
  • 0
    Я считаю, что вы не правы. В вашем примере используется шестнадцатеричная строка, которая НЕ является строкой, а является числом. Поэтому 1f635 будет таким, какой он есть. Если бы вы вставили «0x1f635», все вышло бы иначе. (то есть: подпрограмма только что вернула бы шестнадцатеричное число, которое вы отправили подпрограмме.) :-)
Показать ещё 2 комментария
10
var number = 3200;
var hexString = number.toString(16);

16 - это основание и 16 шестнадцатеричных чисел: -)

9

Ограничено/заполнено до заданного количества символов:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
  • 1
    Это преобразует число в шестнадцатеричную строку и дополняет начальные нули, это прекрасно!
8

Если вы хотите преобразовать число в шестнадцатеричное представление значения цвета RGBA, я нашел, что это самая полезная комбинация из нескольких советов отсюда:

        function toHexString(n) {
            if(n < 0) {
                n = 0xFFFFFFFF + n + 1;
            }

            return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
        }
8
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
}
  • 0
    +1 спасибо! При работе с CSS, toString (16) важен, поэтому вы получите результаты, такие как FF0000
  • 6
    при работе с css (или svg, который принимает спецификации цвета в стиле css) вы можете обойти весь вопрос, написав color: rgb(r,g,b) где rg и b - десятичные числа.
Показать ещё 1 комментарий
6

Для всех, кого интересует, здесь JSFiddle сравнивает большинство ответов, заданных этому вопросу.

И вот метод, с которым я закончил:

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

Кроме того, имейте в виду, что если вы хотите конвертировать из десятичного в шестнадцатеричный для использования в CSS как тип данных цвета, вы вместо этого предпочитают извлекать значения RGB из десятичной дроби и использовать rgb().

Например (JSFiddle):

var c = 4210330; // your color in decimal format
var rgb = [(c & 0xff0000) >> 16,  (c & 0x00ff00) >> 8,  (c & 0x0000ff)];

// assuming you're using jQuery...
$("#some-element").css("color", "rgb(" + rgb + ")");

Это устанавливает свойство #some-element CSS color в значение rgb(64, 62, 154).

6

AFAIK комментарий 57807 неверен и должен выглядеть примерно так: var hex = Number (d).toString(16); вместо 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;
}
5

Хорошо, ответ уже дан, это бесплатно. Здесь отрегулирована версия ES6:

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' 
  • 0
    В случае несогласия с @HypersoftSystems, если вам это позволяет окружение или ситуация, используйте ES6. Не каждый сценарий должен работать в устаревших интерпретаторах бутлега, также есть причина, связанная с babel. И наконец, ES6 более разборчивый, если вы это знаете. Тем не менее, предоставление стандартных JS-ответов может помочь большему количеству людей, но, учитывая, что для более старых версий JS есть и другие ответы, наличие ответа ES6 выгодно, а разглагольствование «так я и сделал в тот день» определенно не требуется.
  • 0
    Мнения не содержат фактов, поэтому ваш «аргумент» неверен. @ WiR3D
Показать ещё 2 комментария
5

Вы можете проверить следующее Пример JsFiddle или пример кода JS Stackoverflow.

'use strict';

var convertBase = function () {

    function convertBase(baseFrom, baseTo) {
        return function (num) {
            return parseInt(num, baseFrom).toString(baseTo);

        };
    }

    // decimal to hexadecimal
    convertBase.dec2hex = convertBase(10, 16);
    return convertBase;
}();


alert(convertBase.dec2hex('42')); // '2a'
5

А если число отрицательно?

Вот моя версия.

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

Как преобразовать десятичное значение в hex в JavaScript?

Я знаю, что этот вопрос старый, не смог найти жестоко чистого/простого преобразования Dec-Hex, которое не включало беспорядок функций и массивов... поэтому я должен был сделать это для себя. Проводя это, чтобы помочь любому, кто ищет это, знаю, что это спасло бы меня некоторое время. лол

/* Revision: modified coding style, with array instead of a switch. */

function DecToHex( decimal ){ // Data (decimal)

    length = -1;    // Base string length
    string = '';    // Source 'string'

    charactor = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]; // charactor array

        do { // grab each nibble in reverse order because javscript has no unsigned left shift

            string += charactor[ decimal & 0xF ];   // mask byte, get that charactor
            ++length;                               // incriment to length of string

        } while( decimal >>>= 4 ); // for next char 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( hexadecial );

}


/* 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 hex equivalent
  • 4
    О боже ... это действительно ужасный, ужасный способ сделать это, сделанный в еще более уродливом стиле кодирования. Честно говоря: что не так с переносами строк и отступами? Однобуквенные переменные? В самом деле?
  • 0
    Пересмотрел это. Это ужасно? И стиль лучше? Первоначально я думал, что будет легче понять, что каждый шаг, «буквально» описанный буквально так, иногда я могу быть довольно глупым
Показать ещё 3 комментария
4

Как принято в ответе, самый простой способ преобразования из dec в hex - var hex = dec.toString(16). Тем не менее, вы можете предпочесть добавить преобразование строк, поскольку оно гарантирует правильную работу строковых представлений, таких как "12".toString(16).

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

Чтобы обратить вспять процесс, вы также можете использовать приведенное ниже решение, так как оно еще короче.

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

В Google Chrome и Firefox он медленнее, но в Opera гораздо быстрее. См. http://jsperf.com/hex-to-dec.

4

Я делаю преобразование в шестнадцатеричную строку в довольно большом цикле, поэтому я попробовал несколько методов, чтобы найти самый быстрый. Мои требования состояли в том, чтобы в результате получить строку с фиксированной длиной и правильно закодировать отрицательные значения (-1 = > ff..f).

Простой .toString(16) не работал у меня, так как мне нужны отрицательные значения для правильной кодировки. Следующий код самый быстрый, который я тестировал до сих пор по 1-2 байтовым значениям (обратите внимание, что symbols определяет количество выводимых символов, которое вы хотите получить, то есть для 4-байтового целого оно должно быть равно 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;
}

Он работает быстрее, чем .toString(16) на 1-2 байтовых числах и медленнее на больших числах (при symbols >= 6), но все же должен превосходить методы, которые правильно кодируют отрицательные значения.

2

Подводя итог,

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

Однако, если вам не нужно преобразовывать его обратно в целое число в конце (т.е. для цветов), достаточно просто убедиться, что значения не являются отрицательными.

1

Я знаю, что этот вопрос старый, но я не нашел четкого ответа, без проверок, если он отрицательный или положительный, который использует два дополнения (включая отрицательные числа). Для этого я показываю свое решение на один байт:

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

Вы можете использовать эту инструкцию для любого числа байтов, только вы добавляете FF в соответствующие места. Например, до 2 байтов:

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

Если вы хотите, чтобы целое число целых чисел было равно string:

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

Извините за реактивную старую нить.

0

Вы можете сделать что-то подобное в ES6:

const toHex = num => (num).toString(16).toUpperCase();
0

Если вы хотите конвертировать в "полное" представление JS или CSS, вы можете использовать что-то вроде:

  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
-4

Никто не ответил на этот вопрос эффективно, поэтому вот мое решение:

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

В вопросе говорится: "КАК ПРЕОБРАЗОВАТЬ ВЕРНУТЬСЯ В HEX В JAVASCRIPT". Хотя в вопросе не указано, что шестнадцатеричная строка должна начинаться с префикса 0x, любой, кто пишет код, должен знать, что 0x добавляется в шестнадцатеричные коды, чтобы отличать HEX-коды от PROGRAMMATIC-IDENTIFIERS и OTHER-NUMBERS (1234 может быть hexi -десятичные, десятичные или даже восьмеричные).

Поэтому, чтобы правильно ответить на этот вопрос, для написания сценариев необходимо добавить префикс 0x.

Функция Math.abs(N) конвертирует негативы в позитивы, и в качестве бонуса не похоже, чтобы кто-то пробежал через дровосек.

Ответ, который я хотел получить, имел бы спецификатор ширины поля, чтобы мы могли, например, отображать 8/16/32/64-битные значения так, как вы видите их в списке в приложении для редактирования в шестнадцатеричном формате. Это фактический, правильный ответ.

  • 0
    В общей практике кодирования любая буквенно-цифровая последовательность, начинающаяся с буквы, НЕ является НОМЕРОМ. Например: ABCDEF012345678 является допустимым идентификатором почти во всех языках кодирования на планете.
  • 0
    Да, и префикс 0x не является проблемой для javascript: Number('0xFF') === 255; для всех вас, кто хочет обратную операцию.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню