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

1479

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

Люк Смит
источник
7
Просто предупреждение, что вы начинаете со строкового представления, очень легко потерять точность, когда вы превращаете его в число как часть преобразования его в шестнадцатеричное. См. Danvk.org/wp/2012-01-20/… .
Studgeek
Эта функция именно то, что вам нужно
Мухаммед Мусави,

Ответы:

2476

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

hexString = yourNumber.toString(16);

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

yourNumber = parseInt(hexString, 16);
Prestaul
источник
42
yourNum - это шестнадцатеричная строка в этом случае. Например (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul
8
@forste, вы не «потеряете точность», если преобразуете номер JavaScript (то есть объект Number, который в сценарии ECMA - Double) в hex и обратно, используя эту технику. Вопрос, который вы связали, специально ссылается на числа, слишком большие, чтобы поместиться в Double (отсюда и строковое представление в вопросе). Если у вас есть номер, то это будет работать. Если у вас есть что-то слишком большое для javascript объекта Number (Double), вам придется найти что-то еще.
Prestaul
12
@Derek, у меня психологическая проблема, которая не позволяет мне терпеть ненужные скобки ... @ всем остальным, yourNumberэто переменная. Если вы хотите использовать числовой литерал, вам нужно будет сделать что-то вроде этого (45).toString(16), но если вы жестко кодируете число, просто напишите его в виде шестнадцатеричной строки ... (45).toString(16)всегда будет равным '2d', так что не тратьте процессор циклы, чтобы понять это.
Prestaul
21
@Prestaul «Не тратьте циклы процессора, чтобы понять это» - это называется преждевременной оптимизацией. Если JavaScript не работает на 286, я сомневаюсь, что накладные расходы имеют значение. Кроме того, «45» может быть магическим числом, которое программист должен уметь распознать (например, длительность тайм-аута в секундах), тогда как «2d», ну кто же это может узнать?
Деджей Клейтон,
47
Если вам не нравятся круглые скобки, вы можете просто использовать дополнительную точку:42..toString(16)
Томас Уотсон
142

Если вам нужно обрабатывать такие вещи, как битовые поля или 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));

пройдоха
источник
5
это дополнение двух?
Джулиан
2
Это преобразование обычно не требуется, поскольку JavaScript может представлять все 32-разрядные битовые поля в виде чисел без знака (см. Number.MAX_SAFE_INTEGER). По той же причине преобразование в неподписанное может быть записано как:number = 0x100000000 + number;
Йоханнес Матокич
3
Краткое примечание к моему предыдущему комментарию: хотя шестнадцатеричное представление должно работать для чисел вплоть до Number.MAX_SAFE_INTEGER, это не относится к побитовым операциям (которые часто используются для создания 32-битных цветов). Результатом побитовых операций всегда является 32-разрядное целое число со знаком. Поэтому побитовые результаты> = 2 ^ 31 отрицательны и 0x100000000 | 0 === 0.
Йоханнес Матокич
25
Вы можете использовать >>>оператор для преобразования числа в беззнаковое представление, например, ((-3253) >>> 0).toString(16)возвращает "fffff34b".
csharpfolk
1
+1для полезного дополнения, но если вы конвертируете числа в другую запись, все числа уже «обычно» положительны, иначе вы хотите получить отрицательные результаты.
Карл Смит
82

Приведенный ниже код преобразует десятичное значение 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;
}
Люк Смит
источник
5
Это не будет правильно обрабатывать отрицательные значения. decimalToHex (-6, 4) вернет 00-6.
JonMR
3
У него также есть проблемы с плавающей точкой, но исправление Math.round () исправило это. (+ 1ed)
Майкл - Где
Я "вытягиваю" числа из массива ('255,0,55' и т. Д.), И .toString (16) не работает. Все, что я получил, было одинаковыми номерами! Я добавил функцию «Число» на фронт, и теперь она работает! Только потратил около четырех часов, пытаясь найти решение !!
Кристофайр
65
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
Baznr
источник
1
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Лори
2
Расширить его не так уж и сложно, вы отсекаете последние цифры с помощью .slice (-number). Если вы добавите больше нулей на фронт, это будет работать нормально.
Tatarize
19
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')😁
Фам
39

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

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

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

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

Alberto
источник
2
это, безусловно, самый ценный ответ на этот вопрос :)
albertjan
Копаться по всем вопросам, потому что C# number to hexadecimalдает разные результаты Javascript number to hexadecimal. Похоже, у Javascript есть проблема с отрицательными числами. Этот ответ кажется решением проблемы.
Goamn
Это было очень полезно, спасибо! Я использовал это для цветов RGB, поэтому, чтобы получить 24-битный вариант, отбейте первые два символа (дополнительный FF) -((-2)>>>0).toString(16).substring(2)
antonyh
36

С прокладкой:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
Фабио Феррари
источник
2
@Lucas Возвращает последние 4 символа.
Габриэль
19

Без цикла:

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++){}
mystifeid
источник
19

Объединение некоторых из этих хороших идей для шестнадцатеричной функции RGB-значения-значения (добавьте #другое место для 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);
}
Кит Машинтер
источник
Спасибо за это! Я хочу оставить комментарий давным-давно. Это был ключ к моему ответу. stackoverflow.com/questions/5560248/…
Pimp Trizkit
16

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

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). Или, другими словами, шестнадцатеричное значение 0xF приводит к тому, что значение с плавающей запятой переводится в целое число, прежде чем оно будет равно ANDed, которое удаляет все, что находится за периодом. Вместо того, чтобы принимать значение в целом (то есть: 3.14159265) и сравнивать значение с плавающей запятой со значением 0xF.

Поэтому в данном случае лучше всего преобразовать 3.14159265 в строку а затем просто преобразовать строку. Из-за вышеизложенного также легко конвертировать отрицательные числа, потому что знак минус становится 0x26 на передней части значения.

Итак, я решил определить, что переменная содержит число - просто преобразовать его в строку и преобразовать строку. Это значит для всех, что на стороне сервера вам нужно будет отсоединить входящую строку, а затем определить, что входящая информация является числовой. Вы можете сделать это легко, просто добавив "#" в начале чисел и "A" в начале строки символов, возвращающейся. Смотрите функцию toHex ().

Радоваться, веселиться!

После еще одного года и долгих раздумий я решил, что функцию "toHex" (а также функцию "fromHex") действительно необходимо обновить. Весь вопрос был «Как я могу сделать это более эффективно?» Я решил, что шестнадцатеричная функция to / from не должна заботиться о том, является ли что-то дробной частью, но в то же время она должна гарантировать, что дробные части включены в строку.

И тогда возник вопрос: «Как вы узнаете, что работаете с шестнадцатеричной строкой?». Ответ прост. Используйте стандартную предстроковую информацию, которая уже признана во всем мире.

Другими словами - используйте «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).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;
}

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

Простой тестовый скрипт, показывающий, что -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 - просто включить в JavaScript функции toHex () и fromHex ().

Марк Мэннинг
источник
Я думаю, что у вас все еще есть работа, которую вы можете выполнять здесь, например, if( s.substr(0,2)раньше, if (typeof s != "string")наверное, не то, что вы хотите. То, что я вернул, тоже не то, что я ожидал ( toHex(0x1f635)дает "0x313238353635"). Не исследовал дальше.
ruffin
Я считаю, что вы не правы. В вашем примере используется шестнадцатеричная строка, которая НЕ является строкой, а является числом. Поэтому 1f635 будет таким, какой он есть. Если бы вы вставили «0x1f635», все вышло бы иначе. (то есть: подпрограмма только что вернула бы шестнадцатеричное число, которое вы отправили подпрограмме.) :-)
Марк Мэннинг
Первым пунктом было то, что вы не можете использовать substr& toLowerCaseдля не-строки ... так что либо typeofнужно прийти раньше, либо, если вы ожидаете toHexбросить не-строку прямо здесь, вы должны полностью удалить typeofпроверку. Есть смысл? То есть, если бы я использовал здесь код без правок и позвонил toHex(0x1f635), я бы получил Uncaught TypeError: s.substr is not a function. Если я перенесу приведенную ранее строку, то вы правы, возможно, число сначала преобразуется в десятичную, и все идет вбок. Что, конечно, означает, что вы не можете выполнять простое приведение здесь, если sэто не строка.
Ерш
На самом деле под XP это работает нормально. В Javascript был внесен ряд обновлений, которые делают Javascript типизированным. Который бросил бы исключение. Под XP это jusr работает. По крайней мере для меня. В мире типов - вставка "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}" является подходящей. Но ox1f635 все еще не строка. :-)
Марк Мэннинг
12
var number = 3200;
var hexString = number.toString(16);

16 - это основа, и в шестнадцатеричном числе есть 16 значений :-)

Дэнни Уилсон
источник
12

Для тех, кто заинтересован, вот JSFiddle, сравнивающий большинство ответов на этот вопрос .

И вот метод, с которым я в конечном итоге пошел:

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

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

Например ( 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 + ')')

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

Шляпа
источник
10

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

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
Adamarla
источник
2
Это преобразует число в строку шестнадцатеричный И колодки ведущие нули, это прекрасно!
Гордон
10

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

источник
1
+1 спасибо! При работе с CSS, toString (16) важен, поэтому вы получите результаты, такие как FF0000
Тайлер Эджето
7
при работе с css (или svg, который принимает спецификации цвета в стиле css) вы можете обойти весь вопрос, написав color: rgb(r,g,b)где rg и b - десятичные числа.
Телент
1
Должно быть: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

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

function toHexString(n) {
    if(n < 0) {
        n = 0xFFFFFFFF + n + 1;
    }
    return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}
Korona
источник
8

AFAIK комментарий 57807 не так и должно быть что - то вроде: вар гекс = 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;
}
скоро
источник
6

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

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

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
источник
5

Я делаю преобразование в шестнадцатеричную строку в довольно большом цикле, поэтому я попробовал несколько методов, чтобы найти самый быстрый. Моими требованиями было получить строку фиксированной длины и правильно кодировать отрицательные значения (-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), но все же должен превосходить методы, которые правильно кодируют отрицательные значения.

Almaz
источник
5

Как говорится в принятом ответе, самый простой способ преобразования из десятичного в шестнадцатеричное - это 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 .

RD
источник
5

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

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

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
источник
5
О боже ... это действительно ужасный, ужасный способ сделать это, сделанный в еще более уродливом стиле кодирования. Честно говоря: что не так с переносами строк и отступами? Однобуквенные переменные? В самом деле?
Виктор Шредер
1
Пересмотрел это. Это ужасно? И стиль лучше? Первоначально я думал, что будет легче понять, что каждый шаг, «буквально»
описанный
4
Извините, да, все еще ужасно. Ваш код по-прежнему использует много неэффективных циклов и загрязняет глобальное пространство имен, среди других проблем. Сам подход является избыточным для задачи, которая может быть выполнена простым вызовом функции. Если вы хотите улучшить свой стиль кодирования в JS, я настоятельно рекомендую вам ознакомиться с такими материалами, как w3.org/wiki/JavaScript_best_practices и google.github.io/styleguide/javascriptguide.xml . Просто гуглите по этому поводу.
Виктор Шредер
1
Я выполнил тест скорости в Chrome, и моя функция переполнения примерно на 30% быстрее, чем .toString (16), тогда как в Firefox моя функция на 40% медленнее, чем .toString (16) ... Chrome доказывает, что мои чрезмерные циклы более эффективны чем функция .toString (16) браузера, в то время как Firefox доказывает, почему все больше людей предпочитают Chrome. Или это назад ?? Однажды Chrome может даже обновиться до более быстрого .toString (16), что сделает меня неправильным в обоих случаях! В любом случае, я не совсем неправ, а ты не совсем прав. Хотя мое эго в стороне, я получаю вашу точку зрения по крайней мере 30% от этого. ;)
JonLikeSquirrel
2
Вам никогда не нужно объявлять массив строк, содержащих по одному символу в каждой. Просто объявите строку символов. Вы можете получить символ из строки, как если бы вы использовали массив, используя квадратные скобки.
Дэвид Спектор
3

Подводя итог всему этому;

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

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

realkstrawn93
источник
2

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

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

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

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

Если вы хотите привести массив целое к шестнадцатеричной строке:

s = "";
for(var i = 0; i < arrayNumber.length; ++i) {
    s += ((0xFF + arrayNumber[i] +1) & 0x0FF).toString(16);
}
Франциско Мануэль Гарка Ботелла
источник
2

Если вы хотите преобразовать в «полное» представление JavaScript или 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
DHC
источник
2

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

const toHex = num => (num).toString(16).toUpperCase();
Алиреза
источник
1

Если вы хотите преобразовать большие целые числа, то есть числа больше чем Number.MAX_SAFE_INTEGER - 9007199254740991, то вы можете использовать следующий код

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

Абхилаш Наяк
источник
1

Это основано на решениях Prestaul и Tod. Тем не менее, это обобщение, которое учитывает переменный размер переменной (например, анализ значения со знаком из последовательного журнала микроконтроллера).

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

Тестовый скрипт:

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

Результаты теста:

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'

Примечание: не слишком уверен, почему он терпит неудачу выше 32 бит

Брайан
источник
-3

Вот мое решение:

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

Вопрос говорит: «Как преобразовать десятичное в шестнадцатеричное в JavaScript» . Хотя в вопросе не указано, что шестнадцатеричная строка должна начинаться с префикса 0x, любой, кто пишет код, должен знать, что 0x добавляется к шестнадцатеричным кодам, чтобы отличать шестнадцатеричные коды от программных идентификаторов и других чисел. (1234 может быть шестнадцатеричным, десятичным или четное восьмеричное).

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

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

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

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