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

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

Просто предупреждение здесь, что вы начинаете со строкового представления, его очень легко потерять точность, когда вы превращаете его в Number как часть преобразования в шестнадцатеричный. См. danvk.org/wp/2012-01-20/….

studgeek 02.06.2013 09:38
Этот function is exactly what you need
Muhammad Musavi 05.09.2018 20:28
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1 610
2
1 035 262
29
Перейти к ответу Данный вопрос помечен как решенный

Ответы 29

Ответ принят как подходящий

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

hexString = yourNumber.toString(16);

И отмените процесс с помощью:

yourNumber = parseInt(hexString, 16);

разве это не yourNum = parseInt (yourNum, 10); - а не 16?

arxpoetica 04.07.2011 17:04

yourNum в данном случае - шестнадцатеричная строка. Например. (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255

Prestaul 08.07.2011 23:14

Может ли кто-нибудь указать мне документацию по параметрам toString()? У меня это работает, но я хотел бы немного отформатировать строку. Согласно MDN, toString() не принимает никаких параметров: developer.mozilla.org/en/JavaScript/Reference/Global_Objects‌ /…

Jonathan M 01.02.2012 03:29

Вы смотрели Object.toString. Вам нужен Number.toString() ... developer.mozilla.org/en/JavaScript/Reference/Global_Objects‌ /…

Prestaul 02.02.2012 01:50

при больших числах очевидно теряется точность. См. мой вопрос

forste 27.03.2012 16:33

@forste, вы не потеряете точность, если конвертируете javascript Number (то есть объект Number, который в сценарии ECMA является Double) в шестнадцатеричный и обратно, используя эту технику. Вопрос, который вы связали, конкретно ссылается на числа, слишком большие, чтобы поместиться в Double (отсюда и строковое представление в вопросе). Если у вас есть номер, это сработает. Если у вас есть что-то слишком большое, чтобы быть объектом javascript Number (Double), вам придется найти что-то еще.

Prestaul 30.03.2012 09:36

@ Дерек, у меня психологическая проблема, из-за которой я не могу терпеть ненужные скобки ... @ все остальные, yourNumber - это переменная. Если вы хотите использовать числовой литерал, вам нужно будет сделать что-то вроде (45).toString(16), но если вы жестко кодируете число, просто напишите его как шестнадцатеричную строку самостоятельно ... (45).toString(16) всегда будет равно '2d', так что не тратить циклы процессора, чтобы понять это.

Prestaul 14.06.2012 23:01

@Prestaul - var a = 16.toString(16) ==> SyntaxError: Unexpected token ILLEGAL Вы должны указать число в скобках.

Derek 朕會功夫 14.06.2012 23:46

@Derek, пожалуйста, перечитайте мой предыдущий комментарий, где я поясняю: 1) что yourNumber - это переменная, а не числовой литерал, и 2) почему вам никогда не нужно вводить (16).toString(16)

Prestaul 15.06.2012 00:41

@Derek 朕 會 功夫 Жаль, что ты удалил все свои комментарии. : P Хотелось бы увидеть обсуждение полностью.

Victor Zamanian 04.01.2014 21:40

@Prestaul «Не тратьте зря циклы процессора, чтобы понять это» - это называется преждевременной оптимизацией. Если только JavaScript не работает на 286, я сомневаюсь, что накладные расходы имеют значение. Кроме того, «45» может быть магическим числом, которое программист должен уметь распознать (например, продолжительность тайм-аута в секундах), тогда как «2d», ну кто это распознает?

Dejay Clayton 12.03.2014 19:02

@DejayClayton, я с тобой согласен. Ясность / простота вместо преждевременной оптимизации. Однако на мой взгляд, есть два основных случая. Во-первых, вы имеете дело с двоичными / шестнадцатеричными данными, и в этих случаях шестнадцатеричная запись более понятна, чем десятичная. (например, 'ff' яснее, чем 255). Другой заключается в том, что у вас есть числовые данные (ваш пример) с шестнадцатеричной кодировкой, и в этих случаях я думаю, что проще назначить числовое значение и не кодировать, пока вам не понадобится шестнадцатеричная строка. например (var timeout = 45; ... doSomething(timeout.toString(16));)

Prestaul 14.03.2014 19:19

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

Thomas Watson 24.07.2014 23:55

Стоит отметить, что это не ограничивается шестнадцатеричным числом, вы также можете использовать восьмеричное или двоичное с toString(8) и toString(2) - а также любую другую базу, которую вы должны выбрать!

mcfedr 02.03.2016 18:47

@ThomasWatson, что это за колдовство?

Ciprian Tomoiagă 10.03.2017 14:25

@CiprianTomoiaga В JavaScript все числа являются числами с плавающей запятой. Итак, 42 - это то же самое, что 42.0. Но можно опустить ноль и написать 42.. Таким образом, если вы напишете 42.toString(16), точка будет отображаться не так, как если бы вы пытались вызвать функцию, а как десятичную точку. Итак, чтобы на самом деле вызвать функцию, вам нужно добавить дополнительный период после десятичной точки.

Thomas Watson 12.03.2017 00:24

В случае, если некоторые люди могут захотеть преобразовать большое целое число, они могут взглянуть здесь: stackoverflow.com/questions/18626844/…

Walty Yeung 10.05.2017 14:25

И если вам не нравятся круглые скобки или лишняя точка, добавьте пробел: 42 .toString(16)

Olivier 06.08.2017 09:17

Есть ли самая короткая форма для преобразования шестнадцатеричного-> десятичного числа вместо parseInt(x,16)?

gkucmierz 09.09.2017 12:38

@gkucmierz, я не думаю, что это станет короче этого. Не сильно отличается от python (int(x, 16)), java (Integer.parseInt(x, 16)) или go (strconv.ParseInt(x, 16, 64)) или почти любого другого языка.

Prestaul 06.10.2017 22:28

@gkucmierz Вы можете обернуть его функцией const parseHex = x => parseInt(x, 16), а затем использовать как parseHex('ff'), который возвращает 255.

Gabriel 19.12.2017 18:24

Приведенный ниже код преобразует десятичное значение 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.

JonMR 17.06.2010 22:09

У него также есть проблемы с поплавками, но использование Math.round () исправило это. (+1)

Michael 30.03.2012 22:13

Я «вытаскиваю» числа из массива ('255,0,55' и т. д.), И .toString (16) не работает. Все, что у меня было, это те же числа! Я добавил функцию "Число" на передний план, и теперь она работает! Я потратил около четырех часов на то, чтобы найти решение !!

Cristofayre 25.05.2020 11:30

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;

Johannes Matokic 22.10.2014 13:35

Небольшое примечание к моему предыдущему комментарию: шестнадцатеричное представление должно работать для чисел до Number.MAX_SAFE_INTEGER, это не относится к побитовым операциям (которые часто используются для создания 32-битных цветов). Результатом поразрядных операций всегда является 32-битное целое число со знаком. Следовательно, побитовые результаты> = 2 ^ 31 отрицательны и 0x100000000 | 0 === 0.

Johannes Matokic 18.02.2015 18:47

Вы можете использовать оператор >>> для преобразования числа в представление без знака, например. ((-3253) >>> 0).toString(16) возвращает "fffff34b".

csharpfolk 21.07.2015 19:29

+1 для полезного дополнения, но если вы конвертируете числа в другую нотацию, все числа уже «обычно» положительны, иначе вы хотите получить отрицательные результаты.

Carl Smith 12.09.2019 06:32

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.

Tyler Egeto 21.02.2011 09:54

при работе с css (или svg, который принимает спецификации цвета в стиле css) вы можете обойти всю проблему, написав color: rgb(r,g,b), где r g и b - десятичные числа.

telent 27.02.2011 14:09

Должно быть: 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 20.05.2011 13:04

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 символа.

Gabriel 19.12.2017 18:29

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

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}

Это преобразует число в шестнадцатеричную строку И дополняет начальные нули, это прекрасно!

Gordon 20.08.2015 12:24

Если вы хотите преобразовать число в шестнадцатеричное представление значения цвета 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); }

Lori 28.12.2016 07:01

Продлить его не так уж и сложно, вы отсекаете последние цифры с помощью .slice (-number). Если вы добавите больше нулей вперед, все будет нормально.

Tatarize 10.01.2017 10:00

ES6 const hex = d => Number(d).toString(16).padStart(2, '0') ?

Ninh Pham 14.09.2017 17:48

Объединение некоторых из этих хороших идей для функции преобразования значения 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 04.02.2014 04:51

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

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

albertjan 04.10.2015 15:18

Копаемся во всех вопросах, потому что C# number to hexadecimal дает результаты, отличные от Javascript number to hexadecimal. Похоже, в Javascript проблема с отрицательными числами. Этот ответ кажется решением проблемы.

goamn 17.04.2019 03:13

Это было очень полезно, спасибо! Я использовал это для цветов RGB, поэтому, чтобы получить 24-битный вариант, нарежьте первые два символа (дополнительный FF) - ((-2)>>>0).toString(16).substring(2)

antonyh 13.09.2019 12:52

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

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"). Дальнейшего расследования не проводилось.

ruffin 30.11.2017 18:59

Я считаю, что вы ошибаетесь. В вашем примере используется шестнадцатеричная строка, которая НЕ является строкой, а является числом. Следовательно, 1f635 вышел бы таким, какой он есть. Если бы вы поставили «0x1f635», получилось бы иначе. (то есть: процедура просто вернула бы шестнадцатеричное число, которое вы отправили в процедуру.) :-)

Mark Manning 03.12.2017 21:42

Первый момент заключался в том, что вы не можете использовать substr и toLowerCase для нестроковых ... так что либо typeof должен появиться раньше, либо, если вы ожидали, что toHex бросит нестроковые прямо здесь, вы должны удалить typeof проверю полностью. Есть смысл? То есть, если бы я использовал здесь код без правок и называл бы toHex(0x1f635), я бы получил Uncaught TypeError: s.substr is not a function. Если я перенесу преобразование строки раньше, вы правы, число сначала будет преобразовано в десятичное, и все пойдет не так. Что, конечно, означает, что вы не можете выполнить здесь простое приведение, если s не является строкой.

ruffin 04.12.2017 16:59

Собственно, под XP это нормально работает. В Javascript был внесен ряд обновлений, которые делают Javascript типизированным. Что вызовет исключение. Под XP работает jusr. По крайней мере для меня. В мире приведения типов - уместно поставить "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}". Но ox1f635 все равно не струна. :-)

Mark Manning 06.12.2017 19:52

Кому интересно, вот 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

О боже ... это действительно ужасный, ужасный способ сделать это, используя еще более уродливый стиль программирования. Честно говоря: что не так с переносами строк и отступами? Однобуквенные переменные? Действительно?

Victor Schröder 20.11.2016 01:42

Пересмотрел. Это ужасно? И стиль лучше ?? Изначально я думал, что будет легче понять каждый шаг, «буквально» прописанный буквами ... иногда я могу быть довольно глупым

JonLikeSquirrel 26.11.2016 07:17

Извините, да, все равно ужасно. Ваш код по-прежнему использует множество неэффективных циклов и, среди прочего, загрязняет глобальное пространство имен. Сам по себе подход является излишним для задачи, которую можно выполнить простым вызовом функции. Если вы хотите улучшить свой стиль кодирования на JS, я настоятельно рекомендую вам прочитать такие материалы, как w3.org/wiki/JavaScript_best_practices и google.github.io/styleguide/javascriptguide.xml. Просто погуглите по теме.

Victor Schröder 23.12.2016 21:33

Я провел тест скорости в Chrome, и моя функция overkill примерно на 30% быстрее, чем .toString (16), в то время как в Firefox моя функция на 40% медленнее, чем .toString (16) ... Chrome доказывает, что мои избыточные циклы БОЛЕЕ эффективны чем встроенная в браузеры функция .toString (16), а Firefox доказывает, почему все больше людей предпочитают Chrome. Или это наоборот ?? Однажды Chrome может даже обновиться до более быстрого .toString (16), что сделает меня неверным в обоих случаях! В любом случае я не совсем ошибаюсь, и вы не совсем правы. Хотя, не говоря уже о моем эго, я понимаю вашу точку зрения, по крайней мере, на 30%. ;)

JonLikeSquirrel 24.12.2016 07:45

Вам никогда не нужно объявлять массив строк, каждая из которых содержит отдельные символы. Просто объявите строку символов. Вы можете получить символ из строки, как и в случае с массивом, используя квадратные скобки.

David Spector 21.10.2018 04:03

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

((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 12.12.2018 12:11

Мнения не подтверждают факты, поэтому ваш «аргумент» неверен. @ WiR3D

Hypersoft Systems 06.01.2019 11:41

@HypersoftSystems он так же действителен, как и ваш, если не больше, поскольку ваш так же самоуверен и ограничивает контекст контекстом, который, вероятно, недействителен в большинстве современных приложений.

WiR3D 09.01.2019 15:48

ошибка пользователя: «столь же самоуверенный», «вероятно» и «наиболее».

Hypersoft Systems 22.01.2019 08:30

Если вы хотите преобразовать в «полное» представление 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 - действительный идентификатор почти на каждом языке кодирования на планете.

Hypersoft Systems 20.11.2018 11:53

Да, и префикс 0x не является проблемой для javascript: Number('0xFF') === 255; для всех тех, кто хочет обратную операцию.

Hypersoft Systems 20.11.2018 12:03

Вы можете сделать что-то подобное в 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=75
  • целая часть в шестнадцатеричный:
    • если i='0' остановится
    • получить по модулю: m=i%16 (с произвольной точностью)
    • преобразовать m в шестнадцатеричную цифру и поместить в строку результата
    • для следующего шага вычислить целую часть i=i/16 (с произвольной точностью)
  • дробная часть
    • считать дробные цифры n
    • умножить k=f*16 (с произвольной точностью)
    • разделите k на правую часть с цифрами n и поместите их в f, а левую часть с остальными цифрами и поместите их в d
    • преобразовать d в шестнадцатеричный и добавить к результату.
    • закончить, когда в результате будет достаточно дробных цифр

// @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));

Другие вопросы по теме