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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Преобразуйте число в шестнадцатеричную строку с помощью:
hexString = yourNumber.toString(16);
И отмените процесс с помощью:
yourNumber = parseInt(hexString, 16);
разве это не yourNum = parseInt (yourNum, 10); - а не 16?
yourNum в данном случае - шестнадцатеричная строка. Например. (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Может ли кто-нибудь указать мне документацию по параметрам toString()? У меня это работает, но я хотел бы немного отформатировать строку. Согласно MDN, toString() не принимает никаких параметров: developer.mozilla.org/en/JavaScript/Reference/Global_Objects /…
Вы смотрели Object.toString. Вам нужен Number.toString() ... developer.mozilla.org/en/JavaScript/Reference/Global_Objects /…
при больших числах очевидно теряется точность. См. мой вопрос
@forste, вы не потеряете точность, если конвертируете javascript Number (то есть объект Number, который в сценарии ECMA является Double) в шестнадцатеричный и обратно, используя эту технику. Вопрос, который вы связали, конкретно ссылается на числа, слишком большие, чтобы поместиться в Double (отсюда и строковое представление в вопросе). Если у вас есть номер, это сработает. Если у вас есть что-то слишком большое, чтобы быть объектом javascript Number (Double), вам придется найти что-то еще.
@ Дерек, у меня психологическая проблема, из-за которой я не могу терпеть ненужные скобки ... @ все остальные, yourNumber - это переменная. Если вы хотите использовать числовой литерал, вам нужно будет сделать что-то вроде (45).toString(16), но если вы жестко кодируете число, просто напишите его как шестнадцатеричную строку самостоятельно ... (45).toString(16) всегда будет равно '2d', так что не тратить циклы процессора, чтобы понять это.
@Prestaul - var a = 16.toString(16) ==> SyntaxError: Unexpected token ILLEGAL Вы должны указать число в скобках.
@Derek, пожалуйста, перечитайте мой предыдущий комментарий, где я поясняю: 1) что yourNumber - это переменная, а не числовой литерал, и 2) почему вам никогда не нужно вводить (16).toString(16)
@Derek 朕 會 功夫 Жаль, что ты удалил все свои комментарии. : P Хотелось бы увидеть обсуждение полностью.
@Prestaul «Не тратьте зря циклы процессора, чтобы понять это» - это называется преждевременной оптимизацией. Если только JavaScript не работает на 286, я сомневаюсь, что накладные расходы имеют значение. Кроме того, «45» может быть магическим числом, которое программист должен уметь распознать (например, продолжительность тайм-аута в секундах), тогда как «2d», ну кто это распознает?
@DejayClayton, я с тобой согласен. Ясность / простота вместо преждевременной оптимизации. Однако на мой взгляд, есть два основных случая. Во-первых, вы имеете дело с двоичными / шестнадцатеричными данными, и в этих случаях шестнадцатеричная запись более понятна, чем десятичная. (например, 'ff' яснее, чем 255). Другой заключается в том, что у вас есть числовые данные (ваш пример) с шестнадцатеричной кодировкой, и в этих случаях я думаю, что проще назначить числовое значение и не кодировать, пока вам не понадобится шестнадцатеричная строка. например (var timeout = 45; ... doSomething(timeout.toString(16));)
Если вам не нравятся круглые скобки, вы можете просто использовать дополнительную точку: 42..toString(16)
Стоит отметить, что это не ограничивается шестнадцатеричным числом, вы также можете использовать восьмеричное или двоичное с toString(8) и toString(2) - а также любую другую базу, которую вы должны выбрать!
@ThomasWatson, что это за колдовство?
@CiprianTomoiaga В JavaScript все числа являются числами с плавающей запятой. Итак, 42 - это то же самое, что 42.0. Но можно опустить ноль и написать 42.. Таким образом, если вы напишете 42.toString(16), точка будет отображаться не так, как если бы вы пытались вызвать функцию, а как десятичную точку. Итак, чтобы на самом деле вызвать функцию, вам нужно добавить дополнительный период после десятичной точки.
В случае, если некоторые люди могут захотеть преобразовать большое целое число, они могут взглянуть здесь: stackoverflow.com/questions/18626844/…
И если вам не нравятся круглые скобки или лишняя точка, добавьте пробел: 42 .toString(16)
Есть ли самая короткая форма для преобразования шестнадцатеричного-> десятичного числа вместо parseInt(x,16)?
@gkucmierz, я не думаю, что это станет короче этого. Не сильно отличается от python (int(x, 16)), java (Integer.parseInt(x, 16)) или go (strconv.ParseInt(x, 16, 64)) или почти любого другого языка.
@gkucmierz Вы можете обернуть его функцией const parseHex = x => parseInt(x, 16), а затем использовать как parseHex('ff'), который возвращает 255.
Приведенный ниже код преобразует десятичное значение 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;
}
Это не будет правильно обрабатывать отрицательные значения. decimalToHex (-6, 4) вернет 00-6.
У него также есть проблемы с поплавками, но использование Math.round () исправило это. (+1)
Я «вытаскиваю» числа из массива ('255,0,55' и т. д.), И .toString (16) не работает. Все, что у меня было, это те же числа! Я добавил функцию "Число" на передний план, и теперь она работает! Я потратил около четырех часов на то, чтобы найти решение !!
var number = 3200;
var hexString = number.toString(16);
16 - это основание системы счисления, а в шестнадцатеричном числе 16 значений :-)
Если вам нужно обрабатывать такие вещи, как битовые поля или 32-битные цвета, вам нужно иметь дело с числами со знаком. Функция JavaScript toString(16) вернет отрицательное шестнадцатеричное число, которое обычно не то, что вам нужно. Эта функция делает какое-то сумасшедшее дополнение, чтобы получить положительное число.
function decimalToHexString(number)
{
if (number < 0)
{
number = 0xFFFFFFFF + number + 1;
}
return number.toString(16).toUpperCase();
}
console.info(decimalToHexString(27));
console.info(decimalToHexString(48.6));Это преобразование обычно не требуется, поскольку JavaScript может представлять все 32-битные поля как числа без знака (см. Number.MAX_SAFE_INTEGER). По той же причине преобразование в беззнаковый можно записать как: number = 0x100000000 + number;
Небольшое примечание к моему предыдущему комментарию: шестнадцатеричное представление должно работать для чисел до Number.MAX_SAFE_INTEGER, это не относится к побитовым операциям (которые часто используются для создания 32-битных цветов). Результатом поразрядных операций всегда является 32-битное целое число со знаком. Следовательно, побитовые результаты> = 2 ^ 31 отрицательны и 0x100000000 | 0 === 0.
Вы можете использовать оператор >>> для преобразования числа в представление без знака, например. ((-3253) >>> 0).toString(16) возвращает "fffff34b".
+1 для полезного дополнения, но если вы конвертируете числа в другую нотацию, все числа уже «обычно» положительны, иначе вы хотите получить отрицательные результаты.
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 спасибо! При работе с CSS важен toString (16), поэтому вы получаете такие результаты, как FF0000.
при работе с css (или svg, который принимает спецификации цвета в стиле css) вы можете обойти всю проблему, написав color: rgb(r,g,b), где r g и b - десятичные числа.
Должно быть: 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 }
AFAIK комментарий 57807 неверен и должен выглядеть примерно так: var hex = Число (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;
}
Без петли:
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++){}
С прокладкой:
function dec2hex(i) {
return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
@Lucas Возвращает последние 4 символа.
Ограничено / дополнено заданным количеством символов:
function decimalToHex(decimal, chars) {
return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
Это преобразует число в шестнадцатеричную строку И дополняет начальные нули, это прекрасно!
Если вы хотите преобразовать число в шестнадцатеричное представление значения цвета RGBA, я обнаружил, что это наиболее полезная комбинация нескольких советов отсюда:
function toHexString(n) {
if (n < 0) {
n = 0xFFFFFFFF + n + 1;
}
return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}
А если число отрицательное?
Вот моя версия.
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);
}
function toHex(d) {
return ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Продлить его не так уж и сложно, вы отсекаете последние цифры с помощью .slice (-number). Если вы добавите больше нулей вперед, все будет нормально.
ES6 const hex = d => Number(d).toString(16).padStart(2, '0') ?
Объединение некоторых из этих хороших идей для функции преобразования значения 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/…
Я делаю преобразование в шестнадцатеричную строку в довольно большом цикле, поэтому я попробовал несколько методов, чтобы найти самый быстрый. Мои требования заключались в том, чтобы получить в результате строку фиксированной длины и правильно кодировать отрицательные значения (-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), но все же должен превосходить методы, которые правильно кодируют отрицательные значения.
Как говорится в принятом ответе, самый простой способ преобразования десятичного числа в шестнадцатеричный - 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.
Для полноты, если вы хотите шестнадцатеричное представление отрицательного числа дополнение до двух, вы можете использовать Оператор >>> с нулевым заполнением и сдвигом вправо. Например:
> (-1).toString(16)
"-1"
> ((-2)>>>0).toString(16)
"fffffffe"
Однако есть одно ограничение: Побитовые операторы JavaScript обрабатывают свои операнды как последовательность из 32 бит., то есть вы получаете 32-битное дополнение до двух.
это, безусловно, самый ценный ответ на этот вопрос :)
Копаемся во всех вопросах, потому что C# number to hexadecimal дает результаты, отличные от Javascript number to hexadecimal. Похоже, в Javascript проблема с отрицательными числами. Этот ответ кажется решением проблемы.
Это было очень полезно, спасибо! Я использовал это для цветов RGB, поэтому, чтобы получить 24-битный вариант, нарежьте первые два символа (дополнительный FF) - ((-2)>>>0).toString(16).substring(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;
}
Однако, если вам не нужно преобразовывать его обратно в целое число в конце (например, для цветов), достаточно просто убедиться, что значения не являются отрицательными.
В принятом ответе не учтены однозначные возвращаемые шестнадцатеричные коды. Это легко регулируется:
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 вызывает преобразование значения плавающая точка в целое число перед операцией AND, что удаляет все, что находится за точкой. Вместо того, чтобы брать значение в целом (например: 3.14159265) и выполнять операцию AND для значения плавающая точка против значения 0xF.
Поэтому в этом случае лучше всего преобразовать 3.14159265 в нить, а затем просто преобразовать строку. Из-за вышесказанного это также упрощает преобразование отрицательных чисел, потому что знак минус просто становится 0x26 перед значением.
Итак, я определил, что переменная содержит число - просто преобразовала его в строку и преобразовала строку. Для всех это означает, что на стороне сервера вам нужно будет расшифровать входящую строку, а затем определить, что входящая информация является числовой. Вы можете сделать это легко, просто добавив «#» перед числами и «A» перед возвращающейся символьной строкой. См. Функцию toHex ().
Радоваться, веселиться!
Спустя еще год и долгих размышлений я решил, что функцию «toHex» (а у меня также есть функция «fromHex») действительно нужно переделать. Весь вопрос был в том, "Как я могу сделать это более эффективно?" Я решил, что шестнадцатеричная функция в / из не должна заботиться о том, является ли что-то дробной частью, но в то же время она должна гарантировать, что дробные части включены в строку.
Тогда возник вопрос: «Откуда вы знаете, что работаете с шестнадцатеричной строкой?». Ответ прост. Используйте стандартную предварительную информацию, которая уже известна во всем мире.
Другими словами - используйте «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"). Дальнейшего расследования не проводилось.
Я считаю, что вы ошибаетесь. В вашем примере используется шестнадцатеричная строка, которая НЕ является строкой, а является числом. Следовательно, 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 все равно не струна. :-)
Кому интересно, вот 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-element CSS color значение rgb(64, 62, 154).
Как преобразовать десятичное число в шестнадцатеричное в 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
О боже ... это действительно ужасный, ужасный способ сделать это, используя еще более уродливый стиль программирования. Честно говоря: что не так с переносами строк и отступами? Однобуквенные переменные? Действительно?
Пересмотрел. Это ужасно? И стиль лучше ?? Изначально я думал, что будет легче понять каждый шаг, «буквально» прописанный буквами ... иногда я могу быть довольно глупым
Извините, да, все равно ужасно. Ваш код по-прежнему использует множество неэффективных циклов и, среди прочего, загрязняет глобальное пространство имен. Сам по себе подход является излишним для задачи, которую можно выполнить простым вызовом функции. Если вы хотите улучшить свой стиль кодирования на JS, я настоятельно рекомендую вам прочитать такие материалы, как w3.org/wiki/JavaScript_best_practices и google.github.io/styleguide/javascriptguide.xml. Просто погуглите по теме.
Я провел тест скорости в Chrome, и моя функция overkill примерно на 30% быстрее, чем .toString (16), в то время как в Firefox моя функция на 40% медленнее, чем .toString (16) ... Chrome доказывает, что мои избыточные циклы БОЛЕЕ эффективны чем встроенная в браузеры функция .toString (16), а Firefox доказывает, почему все больше людей предпочитают Chrome. Или это наоборот ?? Однажды Chrome может даже обновиться до более быстрого .toString (16), что сделает меня неверным в обоих случаях! В любом случае я не совсем ошибаюсь, и вы не совсем правы. Хотя, не говоря уже о моем эго, я понимаю вашу точку зрения, по крайней мере, на 30%. ;)
Вам никогда не нужно объявлять массив строк, каждая из которых содержит отдельные символы. Просто объявите строку символов. Вы можете получить символ из строки, как и в случае с массивом, используя квадратные скобки.
Я не нашел четкого ответа, без проверок, является ли он отрицательным или положительным, с использованием дополнения до двух (включая отрицательные числа). Для этого я показываю свое решение для одного байта:
((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);
}
Вот урезанная версия 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
@HypersoftSystems он так же действителен, как и ваш, если не больше, поскольку ваш так же самоуверен и ограничивает контекст контекстом, который, вероятно, недействителен в большинстве современных приложений.
ошибка пользователя: «столь же самоуверенный», «вероятно» и «наиболее».
Если вы хотите преобразовать в «полное» представление 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.info( numToHex(dec) ); // 0x5b2a96
Вот мое решение:
hex = function(number) {
return '0x' + Math.abs(number).toString(16);
}
В вопросе написано: «Как преобразовать десятичное число в шестнадцатеричное в JavaScript». Хотя вопрос не указывает, что шестнадцатеричная строка должна начинаться с префикса 0x, любой, кто пишет код, должен знать, что 0x добавляется к шестнадцатеричным кодам, чтобы отличить шестнадцатеричные коды от программные идентификаторы и другие числа (1234 может быть шестнадцатеричным, десятичным или даже восьмеричным) .
Следовательно, чтобы правильно ответить на этот вопрос, для написания сценария необходимо добавить префикс 0x.
Функция Math.abs (N) преобразует негатив в позитив, и в качестве бонуса не похоже, что кто-то пропустил ее через измельчитель древесины.
В ответе, который я хотел, был бы спецификатор ширины поля, чтобы мы могли, например, показывать 8/16/32/64-битные значения так, как вы бы видели их перечисленными в приложении для редактирования шестнадцатеричных чисел. Это действительно правильный ответ.
В общей практике кодирования любая буквенно-цифровая последовательность, начинающаяся с буквы, НЕ ЯВЛЯЕТСЯ ЧИСЛОМ. Например: ABCDEF012345678 - действительный идентификатор почти на каждом языке кодирования на планете.
Да, и префикс 0x не является проблемой для javascript: Number('0xFF') === 255; для всех тех, кто хочет обратную операцию.
Вы можете сделать что-то подобное в ECMAScript 6:
const toHex = num => (num).toString(16).toUpperCase();
Если вы хотите преобразовать большие целые числа, то есть числа больше Number.MAX_SAFE_INTEGER - 9007199254740991, вы можете использовать следующий код
const hugeNumber = "9007199254740991873839" // Make sure its in String
const hexOfHugeNumber = BigInt(hugeNumber).toString(16);
console.info(hexOfHugeNumber)Это основано на решениях Престола и Тода. Однако это обобщение, которое учитывает различный размер переменной (например, анализ значения со знаком из последовательного журнала микроконтроллера).
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.info(`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 бит.
rgb (255, 255, 255) // возвращает FFFFFF
rgb (255, 255, 300) // возвращает FFFFFF
rgb (0,0,0) // возвращает 000000
rgb (148, 0, 211) // возвращает 9400D3
function rgb(...values){
return values.reduce((acc, cur) => {
let val = cur >= 255 ? 'ff' : cur <= 0 ? '00' : Number(cur).toString(16);
return acc + (val.length === 1 ? '0'+val : val);
}, '').toUpperCase();
}
Это решение принимает входную десятичную строку и возвращает шестнадцатеричную строку. Поддерживаются десятичные дроби. Алгоритм
s), целую часть (i) и дробную часть (f), например, для -123.75 у нас есть s=true, i=123, f=75i='0' остановитсяm=i%16 (с произвольной точностью)m в шестнадцатеричную цифру и поместить в строку результатаi=i/16 (с произвольной точностью)nk=f*16 (с произвольной точностью)k на правую часть с цифрами n и поместите их в f, а левую часть с остальными цифрами и поместите их в dd в шестнадцатеричный и добавить к результату.// @param decStr - string with non-negative integer
// @param divisor - positive integer
function dec2HexArbitrary(decStr, fracDigits=0) {
// Helper: divide arbitrary precision number by js number
// @param decStr - string with non-negative integer
// @param divisor - positive integer
function arbDivision(decStr, divisor)
{
// algorithm https://www.geeksforgeeks.org/divide-large-number-represented-string/
let ans='';
let idx = 0;
let temp = +decStr[idx];
while (temp < divisor) temp = temp * 10 + +decStr[++idx];
while (decStr.length > idx) {
ans += (temp / divisor)|0 ;
temp = (temp % divisor) * 10 + +decStr[++idx];
}
if (ans.length == 0) return "0";
return ans;
}
// Helper: calc module of arbitrary precision number
// @param decStr - string with non-negative integer
// @param mod - positive integer
function arbMod(decStr, mod) {
// algorithm https://www.geeksforgeeks.org/how-to-compute-mod-of-a-big-number/
let res = 0;
for (let i = 0; i < decStr.length; i++)
res = (res * 10 + +decStr[i]) % mod;
return res;
}
// Helper: multiply arbitrary precision integer by js number
// @param decStr - string with non-negative integer
// @param mult - positive integer
function arbMultiply(decStr, mult) {
let r='';
let m=0;
for (let i = decStr.length-1; i >=0 ; i--) {
let n = m+mult*(+decStr[i]);
r= (i ? n%10 : n) + r
m= n/10|0;
}
return r;
}
// dec2hex algorithm starts here
let h= '0123456789abcdef'; // hex 'alphabet'
let m= decStr.match(/-?(.*?)\.(.*)?/) || decStr.match(/-?(.*)/); // separate sign,integer,ractional
let i= m[1].replace(/^0+/,'').replace(/^$/,'0'); // integer part (without sign and leading zeros)
let f= (m[2]||'0').replace(/0+$/,'').replace(/^$/,'0'); // fractional part (without last zeros)
let s= decStr[0]=='-'; // sign
let r=''; // result
if (i=='0') r='0';
while(i!='0') { // integer part
r=h[arbMod(i,16)]+r;
i=arbDivision(i,16);
}
if (fracDigits) r+ = ".";
let n = f.length;
for(let j=0; j<fracDigits; j++) { // frac part
let k= arbMultiply(f,16);
f = k.slice(-n);
let d= k.slice(0,k.length-n);
r+= d.length ? h[+d] : '0';
}
return (s?'-':'')+r;
}
// -----------
// TESTS
// -----------
let tests = [
["0",2],
["000",2],
["123",0],
["-123",0],
["00.000",2],
["255.75",5],
["-255.75",5],
["127.999",32],
];
console.info('Input Standard Abitrary');
tests.forEach(t=> {
let nonArb = (+t[0]).toString(16).padEnd(17,' ');
let arb = dec2HexArbitrary(t[0],t[1]);
console.info(t[0].padEnd(10,' '), nonArb, arb);
});
// Long Example (40 digits after dot)
let example = "123456789012345678901234567890.09876543210987654321"
console.info(`\nLong Example:`);
console.info('dec:',example);
console.info('hex: ',dec2HexArbitrary(example,40));
Просто предупреждение здесь, что вы начинаете со строкового представления, его очень легко потерять точность, когда вы превращаете его в Number как часть преобразования в шестнадцатеричный. См. danvk.org/wp/2012-01-20/….