Ответ 1
Преобразуйте число в шестнадцатеричную строку с помощью:
hexString = yourNumber.toString(16);
И обратный процесс с:
yourNumber = parseInt(hexString, 16);
Как преобразовать десятичные значения в их шестнадцатеричный эквивалент в JavaScript?
Преобразуйте число в шестнадцатеричную строку с помощью:
hexString = yourNumber.toString(16);
И обратный процесс с:
yourNumber = parseInt(hexString, 16);
Если вам нужно обрабатывать такие вещи, как битовые поля или 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));
Код ниже преобразует десятичное значение 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;
}
function toHex(d) {
return ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
С дополнением:
function dec2hex(i) {
return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
Для полноты, если вам нужно шестнадцатеричное представление отрицательного числа с двумя дополнениями, вы можете использовать оператор смещения нуля вправо >>>
. Например:
> (-1).toString(16)
"-1"
> ((-2)>>>0).toString(16)
"fffffffe"
Однако есть одно ограничение: побитовые операторы JavaScript обрабатывают свои операнды как последовательность из 32 битов, то есть вы получаете 32-битное два дополнения.
Без цикла:
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++){}
Объединение некоторых из этих хороших идей для шестнадцатеричной функции 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);
}
В принятом ответе не учитывались однозначные возвращаемые шестнадцатеричные коды. Это легко регулируется:
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 проверяет, есть ли она там и есть ли она - она просто возвращает строку, которая была ему отправлена. В противном случае он преобразует строку, число, что угодно. Вот пересмотренная функция Hex://///////////////////////////////////////////////////////////////////////////////toHex(). Преобразовать строку ASCII в шестнадцатеричное. /////////////////////////////////////////////////////////////////////////////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. Если вы хотите, чтобы он переводил 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().
var number = 3200;
var hexString = number.toString(16);
16 - это основание и 16 шестнадцатеричных чисел: -)
Ограничено/дополнено заданным количеством символов:
function decimalToHex(decimal, chars) {
return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
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
}
Если вы хотите преобразовать число в шестнадцатеричное представление значения цвета RGBA, я считаю, что это наиболее полезная комбинация из нескольких советов:
function toHexString(n) {
if(n < 0) {
n = 0xFFFFFFFF + n + 1;
}
return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}
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;
}
Для всех, кого интересует, здесь 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)
.
Вот урезанная версия 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'
А если число отрицательно?
Вот моя версия.
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);
}
Вы также можете проверить следующий пример JsFiddle или пример кода Qaru JavaScript.
'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'
Я делаю преобразование в шестнадцатеричную строку в довольно большом цикле, поэтому я попробовал несколько методов, чтобы найти самый быстрый. Мои требования состояли в том, чтобы в результате получить строку с фиксированной длиной и правильно закодировать отрицательные значения (-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.
Как преобразовать десятичное в шестнадцатеричное в 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
Подводя итог,
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;
}
Однако, если вам не нужно преобразовывать его обратно в целое число в конце (т.е. для цветов), достаточно просто убедиться, что значения не являются отрицательными.
Я не нашел четкого ответа, без проверок, если он отрицательный или положительный, который использует два дополнения (включая отрицательные числа). Для этого я покажу свое решение на один байт:
((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);
}
Если вы хотите преобразовать в "полное" представление 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
Вы можете сделать что-то подобное в 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.log(hexOfHugeNumber)
Это основано на решениях 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-битного размера.
Вот мое решение:
hex = function(number) {
return '0x' + Math.abs(number).toString(16);
}
Вопрос говорит: "Как преобразовать десятичное в шестнадцатеричное в JavaScript". В то время как вопрос не указывает, что шестнадцатеричная строка должна начинаться с префикса 0x, любой, кто пишет код, должен знать, что 0x добавляется к шестнадцатеричным кодам, чтобы отличать шестнадцатеричные коды от программных идентификаторов и других чисел (1234 может быть шестнадцатеричным, десятичным или четное восьмеричное).
Поэтому, чтобы правильно ответить на этот вопрос, для написания сценариев необходимо добавить префикс 0x.
Функция Math.abs(N) конвертирует негативы в позитивы, и в качестве бонуса не похоже, чтобы кто-то пробежал через дровосек.
Ответ, который я хотел получить, имел бы спецификатор ширины поля, так что мы могли бы, например, показать 8/16/32/64-битные значения так, как вы бы их отобразили в шестнадцатеричном приложении для редактирования. Это фактический, правильный ответ.