Как преобразовать десятичное в шестнадцатеричное в JavaScript?
Как конвертировать десятичные значения в их шестнадцатеричный эквивалент в JavaScript?
32 ответа
Преобразуйте число в шестнадцатеричную строку с помощью:
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()
}
Для завершения, если вы хотите получить шестнадцатеричное представление отрицательного числа с дополнением до двух, вы можете использовать сдвиг нуля-заполнение-вправо >>>
оператор. Например:
> (-1).toString(16)
"-1"
> ((-2)>>>0).toString(16)
"fffffffe"
Однако есть одно ограничение: побитовые операторы javascript обрабатывают свои операнды как последовательность из 32 битов, то есть вы получаете 32-битное двоичное дополнение.
С прокладкой:
function dec2hex(i) {
return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
В принятом ответе не учитываются однозначные возвращаемые шестнадцатеричные коды. Это легко регулируется:
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 до того, как оно будет ANDed, что удаляет все, что находится за периодом. Вместо того, чтобы брать значение в целом (то есть: 3.14159265) и ставить значение ПЛАВУЩЕЙ ТОЧКИ И против значения 0xf. Поэтому в данном случае лучше всего преобразовать 3.14159265 в STRING, а затем просто преобразовать строку. Из-за вышеизложенного также легко конвертировать отрицательные числа, потому что знак минус становится 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) == "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" на передней панели.)
Простой тестовый скрипт, показывающий, что -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.
Без цикла:
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 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);
}
Для всех, кто интересуется, вот 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)
,
Ограничено / дополнено заданным количеством символов:
function decimalToHex(decimal, chars) {
return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
Хорошо, ответ уже дан, это бесплатно. Вот урезанная версия 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'
var number = 3200;
var hexString = number.toString(16);
16 - это основа, и в шестнадцатеричном числе есть 16 значений:-)
Если вы хотите преобразовать число в шестнадцатеричное представление значения цвета RGBA, я считаю, что это наиболее полезная комбинация из нескольких советов:
function toHexString(n) {
if(n < 0) {
n = 0xFFFFFFFF + n + 1;
}
return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-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
}
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;
}
Как говорится в принятом ответе, самый простой способ конвертировать из 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.
А если число отрицательное?
Вот моя версия.
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);
}
Преобразование шестнадцатеричных чисел цвета в шестнадцатеричные цветовые строки:
Простое решение с
toString
и ES6
padStart
для преобразования шестнадцатеричных номеров цветов в шестнадцатеричные цветовые строки.
const string = `#${color.toString(16).padStart(6, '0')}`;
Например:
0x000000
станет
#000000
0xFFFFFF
станет
#FFFFFF
Я делаю преобразование в шестнадцатеричную строку в довольно большом цикле, поэтому я попробовал несколько методов, чтобы найти самый быстрый. Мои требования заключались в том, чтобы в результате иметь строку фиксированной длины и правильно кодировать отрицательные значения (-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), но все равно должны превосходить методы, которые правильно кодируют отрицательные значения.
Вы также можете проверить следующий пример JsFiddle или пример кода JS Stackru.
'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'
Как преобразовать десятичное в шестнадцатеричное в 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
Вы можете сделать что-то подобное в ES6:
const toHex = num => (num).toString(16).toUpperCase();
Подводя итог всему этому;
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 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 бит
Если вы ищете преобразование Больших целых чисел, то есть чисел, больших чем Number.MAX_SAFE_INTEGER - 9007199254740991, то вы можете использовать следующий код
const hugeNumber = "9007199254740991873839" // Make sure its in String
const hexOfHugeNumber = BigInt(hugeNumber).toString(16);
console.log(hexOfHugeNumber)
Я знаю, что этот вопрос старый, но я не нашел четкого ответа, без проверок, если он отрицательный или положительный, который использует дополнение к двум (включая отрицательные числа). Для этого я покажу свое решение на один байт:
((0xFF + number +1) & 0x0FF).toString(16);
Вы можете использовать эту инструкцию для любого количества байтов, только вы добавляете FF в соответствующих местах. Например, до 2 байтов:
((0xFFFF + number +1) & 0x0FFFF).toString(16);
Если вы хотите привести массив целое число в строку hex:
s = "";
for(var i = 0; i < arrayNumber.length; ++i) {
s += ((0xFF + arrayNumber[i] +1) & 0x0FF).toString(16);
}
Извините за реактивную старую ветку.
Если вы хотите преобразовать в "полное" представление 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
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(); }
Проблема в том, сколько нулей можно ожидать.
Если вы ожидаете строку
01
а также
11
из числа 1 и 17. в качестве моста лучше использовать Buffer, с помощью которого число превращается в байты, а затем hex - это просто выходной формат его.А организация байтов хорошо контролируется функциями Buffer, такими как writeUInt32BE, writeInt16LE и т.д.
import { Buffer } from 'buffer';
function toHex(n) { // 4byte
const buff = Buffer.alloc(4);
buff.writeInt32BE(n);
return buff.toString('hex');
}
> toHex(1)
'00000001'
> toHex(17)
'00000011'
> toHex(-1)
'ffffffff'
> toHex(-1212)
'fffffb44'
> toHex(1212)
'000004bc'