Як перетворити десятковий у шістнадцятковий у JavaScript


1479

Як ви конвертуєте десяткові значення у їх шістнадцятковий еквівалент у JavaScript?


7
Тут лише попередження про те, що ви починаєте з подання рядка, дуже легко втратити точність, коли ви перетворите його на номер як частину перетворення його в шістнадцятковий. Дивіться danvk.org/wp/2012-01-20/… .
studgeek

Ця функція саме те, що вам потрібно
Мохаммед Мусаві

Відповіді:


2474

Перетворити число в шістнадцятковий рядок за допомогою:

hexString = yourNumber.toString(16);

І поверніть процес за допомогою:

yourNumber = parseInt(hexString, 16);

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

8
@forste, ви не будете "втрачати точність", якщо перетворите номер JavaScript (тобто об'єкт Number, який у сценарії ECMA є Double) в шестигранний і назад за допомогою цієї методики. Питання, яке ви пов’язали, конкретно посилається на числа, занадто великі, щоб вписатись у подвійний (звідси рядкове представлення у запитанні). Якщо у вас є номер, це спрацює. Якщо у вас є щось занадто велике, щоб бути об’єктом номеру javascript (Double), то вам доведеться знайти щось інше.
Prestaul

12
@Derek, у мене є психологічна проблема, яка не дозволить мені терпіти непотрібні дужки ... @ всі-інші, yourNumberце змінна. Якщо ви хочете використовувати числовий буквал, тоді вам доведеться зробити щось на кшталт (45).toString(16), але якщо ви жорстко кодуєте число, то, будь ласка, просто напишіть його як шістнадцятковий рядок ... (45).toString(16)завжди буде рівним '2d', тому не витрачайте процесор цикли, щоб зрозуміти це.
Prestaul

21
@Prestaul "Не витрачайте цикли процесора, щоб зрозуміти це" - це називається передчасної оптимізацією. Якщо JavaScript не працює на версії 286, я сумніваюся, що над головними питаннями. Крім того, "45" може бути магічним числом, яке програміст повинен вміти розпізнавати (наприклад, тривалість тайм-ауту в секундах), тоді як "2d", ну хто це розпізнає?
Dejay Clayton

47
Якщо вам не подобаються круглі дужки, ви можете просто скористатися додатковою крапкою:42..toString(16)
Томас Уотсон,

142

Якщо вам потрібно обробляти такі речі, як бітові поля або 32-бітні кольори, тоді вам потрібно мати справу з підписаними номерами. Функція JavaScript toString(16)поверне від'ємне шістнадцяткове число, яке зазвичай не є тим, що потрібно. Ця функція робить якесь божевільне доповнення, щоб зробити його додатним числом.

function decimalToHexString(number)
{
  if (number < 0)
  {
    number = 0xFFFFFFFF + number + 1;
  }

  return number.toString(16).toUpperCase();
}

console.log(decimalToHexString(27));
console.log(decimalToHexString(48.6));


5
це доповнення двох?
Джуліан

2
Ця конверсія зазвичай не потрібна, оскільки JavaScript може представляти всі 32-бітні поля у вигляді безпідписаних номерів (див. Номер.MAX_SAFE_INTEGER). З цієї ж причини перехід до непідписаного можна записати так:number = 0x100000000 + number;
Йоганнес Матокич,

3
Коротка примітка до мого попереднього коментаря: Хоча шістнадцяткове представлення повинно працювати для чисел до Число. Результатом бітових операцій завжди є підписане 32-бітове ціле число. Тому побітні результати> = 2 ^ 31 від'ємні і 0x100000000 | 0 === 0.
Йоганнес Матокич

25
Ви можете використовувати >>>оператор для перетворення номера в неподписане представлення, наприклад, ((-3253) >>> 0).toString(16)повернення "fffff34b".
csharpfolk

1
+1для корисного доповнення, але якщо ви перетворюєте числа в інше позначення, всі числа вже "зазвичай" позитивні, інакше ви хочете негативні результати.
Карл Сміт

82

Код нижче перетворить десяткове значення d у шістнадцяткове. Це також дозволяє додати оббивки до шістнадцяткового результату. Тож 0 стане за умовчанням 0.

function decimalToHex(d, padding) {
    var hex = Number(d).toString(16);
    padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

    while (hex.length < padding) {
        hex = "0" + hex;
    }

    return hex;
}

5
Це неправильно обробляє негативні значення. decimalToHex (-6, 4) поверне 00-6.
JonMR

3
У нього також є проблеми з floats, але введення в Math.round () виправлено це. (+ 1ed)
Майкл - Де Глина Ширкі

Я "витягую" числа з масиву ("255,0,55" тощо), і .toString (16) не працює. Все, що я отримав, були однакові! Я додав функцію "Число" на передню частину, і тепер вона працює! Тільки витратив близько чотирьох годин, намагаючись знайти рішення !!
Крістофайр

65
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}

1
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Лорі

2
Розширити це не так складно, ви зрізаєте останні цифри там .slice (-число). Якщо ви додасте більше нулів на фронт, це буде добре.
Татаризація

19
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')😁
Ninh Pham

39

Для повноти, якщо ви хочете, щоб два- шістнадцяткове представлення від'ємного числа, ви можете скористатися оператором зсуву нуля заповнення-право>>> . Наприклад:

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

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

Однак є одне обмеження: побітові оператори JavaScript трактують свої операнди як послідовність 32 біт , тобто ви отримуєте 32-бітний додаток двох.


2
це, безумовно, найцінніша відповідь на це питання :)
albertjan

Копати всі питання, тому що C# number to hexadecimalдавав різні результати Javascript number to hexadecimal. Схоже, у Javascript є проблема з негативними цифрами. Ця відповідь, здається, є вирішенням проблеми.
goamn

Це було дуже корисно, дякую! Я використовував це для кольорів RGB, щоб отримати 24-розрядний варіант, ((-2)>>>0).toString(16).substring(2)
відсікання


19

Без циклу:

function decimalToHex(d) {
  var hex = Number(d).toString(16);
  hex = "000000".substr(0, 6 - hex.length) + hex;
  return hex;
}

// Or "#000000".substr(0, 7 - hex.length) + hex;
// Or whatever
// *Thanks to MSDN

Чи не краще не використовувати циклічні тести, які потрібно оцінити?

Наприклад, замість:

for (var i = 0; i < hex.length; i++){}

мати

for (var i = 0, var j = hex.length; i < j; i++){}

19

Поєднуючи деякі з цих хороших ідей для функції RGB-значення-шістнадцятковий (додайте #інше для HTML / CSS):

function rgb2hex(r,g,b) {
    if (g !== undefined)
        return Number(0x1000000 + r*0x10000 + g*0x100 + b).toString(16).substring(1);
    else
        return Number(0x1000000 + r[0]*0x10000 + r[1]*0x100 + r[2]).toString(16).substring(1);
}

Дякую за це! Я хотів би кинути коментар давно. Це було ключем до моєї відповіді. stackoverflow.com/questions/5560248 / ...
сутенер Trizkit

16

Прийнята відповідь не враховувала однозначні повернені шістнадцяткові коди. Це легко регулюється:

function numHex(s)
{
    var a = s.toString(16);
    if ((a.length % 2) > 0) {
        a = "0" + a;
    }
    return a;
}

і

function strHex(s)
{
    var a = "";
    for (var i=0; i<s.length; i++) {
        a = a + numHex(s.charCodeAt(i));
    }

    return a;
}

Я вважаю, що вищезазначені відповіді неодноразово публікувались у тій чи іншій формі. Я загортаю їх у функцію toHex () так:

function toHex(s)
{
    var re = new RegExp(/^\s*(\+|-)?((\d+(\.\d+)?)|(\.\d+))\s*$/);

    if (re.test(s)) {
        return '#' + strHex( s.toString());
    }
    else {
        return 'A' + strHex(s);
    }
}

Зауважте, що числовий регулярний вираз походить від 10+ корисних функцій регулярного вираження JavaScript для підвищення ефективності веб-додатків .

Оновлення: Після тестування цієї речі кілька разів я виявив помилку (подвійні лапки в RegExp), тому я виправив це. ЗАРАЗ! Провівши трохи тестування та прочитавши повідомлення від almaz - я зрозумів, що не можу отримати негативні цифри для роботи.

Далі - я трохи прочитав це питання, і оскільки всі номери JavaScript зберігаються як 64-бітні слова, незалежно від цього - я спробував змінити код numHex, щоб отримати 64-бітове слово. Але виявляється, ви не можете цього зробити. Якщо ви помістите "3.14159265" ЯК НОМЕР у змінну - все, що вам вдасться отримати, - це "3", оскільки дробова частина доступна лише шляхом множення числа на десять (IE: 10.0) кілька разів. Або кажучи про інший спосіб - шістнадцяткове значення 0xF призводить до того, що значення плаваючої точки переводиться на ціле число до того, як воно буде ANDed, що видаляє все, що знаходиться за періодом. Замість того, щоб приймати значення в цілому (тобто: 3.14159265) і ANDing значення плаваючої точки проти значення 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

Я вважаю, ви неправі. У вашому прикладі використовується шістнадцятковий рядок, який НЕ є рядком, а числом. Тому 1f635 вийде таким, яким він є. Якби ви поставили "0x1f635", це вийшло б інакше. (Тобто процедура б тільки що повернувся шестигранний номер , який був відправлений в рутину.) :-)
Марк Меннінг

Перший момент полягав у тому, що ви не можете використовувати substr& toLowerCaseon-a-string ... тому або typeofпотрібно прийти швидше, або, якщо ви очікували toHexперекидання не рядка прямо там, вам слід повністю зняти typeofчек. Мати сенс? Тобто, якби я тут використав код без правок і зателефонував toHex(0x1f635), я отримав би Uncaught TypeError: s.substr is not a function. Якщо я переміщу рядок, поданий раніше, ти маєш рацію, число, мабуть, переходить у десяткове значення, можливо, і все піде вбік. Що, звичайно, означає, що ви не можете тут виконати простий склад, якщо sце не рядок.
ruffin

Насправді в XP це працює чудово. Існує ряд оновлень Javascript, які роблять Javascript набором тексту. Що би кинуло виняток. Під XP він працює jusr. Принаймні для мене. У світі набору текстів - відповідним є "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}". Але ox1f635 все ще не є рядком. :-)
Марк Маннінг

12
var number = 3200;
var hexString = number.toString(16);

16 - це радіус, і 16 значень у шістнадцятковій кількості :-)


12

Для всіх, хто цікавиться, ось JSFiddle, який порівнює більшість відповідей на це питання .

І ось метод, з яким я закінчився:

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

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

Наприклад ( JSFiddle ):

let c = 4210330 // your color in decimal format
let rgb = [(c & 0xff0000) >> 16,  (c & 0x00ff00) >> 8,  (c & 0x0000ff)]

// Vanilla JS:
document..getElementById('some-element').style.color = 'rgb(' + rgb + ')'
// jQuery:
$('#some-element').css('color', 'rgb(' + rgb + ')')

Це встановлює властивість #some-elementCSS colorдля rgb(64, 62, 154).


10

Обмежений / доповнений заданою кількістю символів:

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

2
Це перетворює число в шістнадцятковий рядок І колодки, що ведуть нулі, це прекрасно!
Гордон

10

Ось оброблена версія ECMAScript 6:

const convert = {
  bin2dec : s => parseInt(s, 2).toString(10),
  bin2hex : s => parseInt(s, 2).toString(16),
  dec2bin : s => parseInt(s, 10).toString(2),
  dec2hex : s => parseInt(s, 10).toString(16),
  hex2bin : s => parseInt(s, 16).toString(2),
  hex2dec : s => parseInt(s, 16).toString(10)
};

convert.bin2dec('111'); // '7'
convert.dec2hex('42');  // '2a'
convert.hex2bin('f8');  // '11111000'
convert.dec2bin('22');  // '10110'

Якщо ви не погоджуєтесь з @HypersoftSystems, якщо ваше оточення чи ситуація дозволяє вам, тоді використовуйте ES6. Не кожен сценарій потребує запуску у застарілих інтерпретаторах бутлегів, також джебл існує з причини. І нарешті, ES6 набагато розбірливіший, якщо ви це знаєте. Це сказано, що надання стандартних відповідей на JS може допомогти більшості людей, але, враховуючи, що є і інші відповіді для старих версій JS, відповідь ES6 є корисним, "так я це зробив ще в той день", звичайно, не потрібно.
WiR3D

Думки не приводять фактів, тому ваш "аргумент" недійсний. @ WiR3D
Hypersoft Systems

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

Помилка користувача: "настільки ж впевнено", "ймовірно" та "найбільше".
Hypersoft Systems

9
function dec2hex(i)
{
  var result = "0000";
  if      (i >= 0    && i <= 15)    { result = "000" + i.toString(16); }
  else if (i >= 16   && i <= 255)   { result = "00"  + i.toString(16); }
  else if (i >= 256  && i <= 4095)  { result = "0"   + i.toString(16); }
  else if (i >= 4096 && i <= 65535) { result =         i.toString(16); }
  return result
}

1
+1 спасибі! Під час роботи з CSS важливо виконувати функцію toString (16), щоб ви отримали такі результати, як FF0000
Tyler Egeto

7
під час роботи з css (або svg, який приймає специфікації кольору стилю css), ви можете пройти повний випуск, написавши, color: rgb(r,g,b)де rg і b - десяткові числа.
телент

1
Повинно бути:function decimalToHexString(i) { var result = "00"; if (i >= 0 && i <= 15) { result += "000" + i.toString(16); } else if (i >= 16 && i <= 255) { result += "00" + i.toString(16); } else if (i >= 256 && i <= 4095) { result += "0" + i.toString(16); } else if (i >= 4096 && i <= 65535) { result += i.toString(16); } return result }
Айкут Шевік

9

Якщо ви хочете перетворити число в шістнадцяткове представлення значення кольору RGBA, я вважаю, що це найкорисніша комбінація кількох порад звідси:

function toHexString(n) {
    if(n < 0) {
        n = 0xFFFFFFFF + n + 1;
    }
    return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}

8

Коментар 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;
}

6

А якщо число від’ємне?

Ось моя версія.

function hexdec (hex_string) {
    hex_string=((hex_string.charAt(1)!='X' && hex_string.charAt(1)!='x')?hex_string='0X'+hex_string : hex_string);
    hex_string=(hex_string.charAt(2)<8 ? hex_string =hex_string-0x00000000 : hex_string=hex_string-0xFFFFFFFF-1);
    return parseInt(hex_string, 10);
}

5

Я роблю перетворення в шістнадцятковий рядок у досить великому циклі, тому я спробував кілька методів, щоб знайти найшвидший. Мої вимоги полягали в тому, щоб у результаті був рядок фіксованої довжини і правильно кодувати негативні значення (-1 => ff..f).

Простий .toString(16)для мене не працював, оскільки мені потрібні були негативні значення для правильного кодування. Наступний код є найшвидшим, який я перевірив на сьогодні, на 1-2 байтні значення (зауважте, що symbolsвизначається кількість вихідних символів, які ви хочете отримати, тобто для 4-байтового цілого числа воно повинно бути рівним 8):

var hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
function getHexRepresentation(num, symbols) {
    var result = '';
    while (symbols--) {
        result = hex[num & 0xF] + result;
        num >>= 4;
    }
    return result;
}

Він працює швидше, ніж .toString(16)на 1-2 байтових числах, і повільніше на більших числах (коли symbols> = 6), але все ж повинен перевершити методи, які кодують негативні значення належним чином.


5

Як зазначається у прийнятій відповіді, найпростіший спосіб перетворення з десяткової в шістнадцяткову var hex = dec.toString(16). Однак ви можете віддати перевагу перетворенню рядків, оскільки це забезпечує правильне представлення рядків "12".toString(16).

// Avoids a hard-to-track-down bug by returning `c` instead of `12`
(+"12").toString(16);

Щоб змінити процес, ви також можете скористатися рішенням нижче, оскільки воно ще коротше.

var dec = +("0x" + hex);

Схоже, це повільніше в Google Chrome і Firefox, але значно швидше в Opera. Дивіться http://jsperf.com/hex-to-dec .


5

Як перетворити десятковий у шістнадцятковий у JavaScript

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

function DecToHex(decimal) { // Data (decimal)

    length = -1;    // Base string length
    string = '';    // Source 'string'

    characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]; // character array

    do { // Grab each nibble in reverse order because JavaScript has no unsigned left shift

        string += characters[decimal & 0xF];   // Mask byte, get that character
        ++length;                              // Increment to length of string

    } while (decimal >>>= 4); // For next character shift right 4 bits, or break on 0

    decimal += 'x'; // Convert that 0 into a hex prefix string -> '0x'

    do
        decimal += string[length];
    while (length--); // Flip string forwards, with the prefixed '0x'

    return (decimal); // return (hexadecimal);
}

/* Original: */

D = 3678;    // Data (decimal)
C = 0xF;    // Check
A = D;        // Accumulate
B = -1;        // Base string length
S = '';        // Source 'string'
H = '0x';    // Destination 'string'

do {
    ++B;
    A& = C;

    switch(A) {
        case 0xA: A='A'
        break;

        case 0xB: A='B'
        break;

        case 0xC: A='C'
        break;

        case 0xD: A='D'
        break;

        case 0xE: A='E'
        break;

        case 0xF: A='F'
        break;

        A = (A);
    }
    S += A;

    D >>>= 0x04;
    A = D;
} while(D)

do
    H += S[B];
while (B--)

S = B = A = C = D; // Zero out variables
alert(H);    // H: holds hexadecimal equivalent

5
О, мій ... це дійсно жахливий, жахливий спосіб зробити це, зроблений у ще більш потворному стилі кодування. Чесно кажучи: що не так з розривами рядків та відступами? Змінні однієї літери? Дійсно?
Віктор Шредер

1
Переглянув його. Чи такий спосіб жахливий? А стиль кращий ?? Спочатку я думав, що легше буде зрозуміти з кожним кроком "буквально" так написано буквами ... іноді я можу бути досить дурним
JonLikeSquirrel

4
Вибачте, так, все ще страшно. Ваш код все ще використовує безліч неефективних циклів і забруднює глобальний простір імен, серед інших проблем. Сам підхід є надмірним для завдання, яке можна виконати за допомогою простого виклику функції. Якщо ви хочете вдосконалити стиль кодування в JS, я настійно рекомендую прочитати такі матеріали, як w3.org/wiki/JavaScript_best_practices та google.github.io/styleguide/javascriptguide.xml . Просто гугл про тему.
Віктор Шредер

1
Я зробив тест на швидкість у Chrome, і моя функція overkill приблизно на 30% швидша, ніж .toString (16), тоді як у Firefox моя функція на 40% повільніше, ніж. ніж функція .toString (16) для браузерів, в той час як Firefox доводить, чому більшість людей віддають перевагу Chrome. Або це назад ?? Один день Chrome може навіть оновитись до швидшого .toString (16), що робить мене в обох випадках неправильним! У будь-якому випадку я не зовсім помиляюся, і ти не зовсім прав. Хоча моє его вбік, я розумію, щонайменше на 30%. ;)
JonLikeSquirrel

2
Вам ніколи не потрібно оголошувати масив рядків, що містять по одному символу. Просто оголосіть рядок символів. Ви можете отримати символ із рядка так само, як і з масивом, використовуючи квадратні дужки.
Девід Спектор

3

Підсумувати все це;

function toHex(i, pad) {

  if (typeof(pad) === 'undefined' || pad === null) {
    pad = 2;
  } 

  var strToParse = i.toString(16);

  while (strToParse.length < pad) {
    strToParse = "0" + strToParse;
  }

  var finalVal =  parseInt(strToParse, 16);

  if ( finalVal < 0 ) {
    finalVal = 0xFFFFFFFF + finalVal + 1;
  }

  return finalVal;
}

Однак, якщо вам не потрібно перетворювати його в ціле число в кінці (тобто для кольорів), достатньо лише переконатися, що значення не є негативними.


2

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

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

Ви можете використовувати цю інструкцію до будь-яких числових байтів, лише додаючи їх FFу відповідних місцях. Наприклад, до двох байтів:

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

Якщо ви хочете привести ціле масив до рядка шістнадцятковим:

s = "";
for(var i = 0; i < arrayNumber.length; ++i) {
    s += ((0xFF + arrayNumber[i] +1) & 0x0FF).toString(16);
}

2

Якщо ви хочете перетворити на "повне" представлення JavaScript або CSS, ви можете використовувати щось на зразок:

  numToHex = function(num) {
    var r=((0xff0000&num)>>16).toString(16),
        g=((0x00ff00&num)>>8).toString(16),
        b=(0x0000ff&num).toString(16);
    if (r.length==1) { r = '0'+r; }
    if (g.length==1) { g = '0'+g; }
    if (b.length==1) { b = '0'+b; }
    return '0x'+r+g+b;                 // ('#' instead of'0x' for CSS)
  };

  var dec = 5974678;
  console.log( numToHex(dec) );        // 0x5b2a96


1

Якщо ви шукаєте для перетворення великих цілих чисел, тобто чисел, більших за число.MAX_SAFE_INTEGER - 9007199254740991, то ви можете використовувати наступний код

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


1

Це засновано на рішеннях Prestaul і Tod. Однак це узагальнення, яке враховує різний розмір змінної (наприклад, Парсинг підписаного значення з послідовного журналу мікроконтролера).

function decimalToPaddedHexString(number, bitsize)
{ 
  let byteCount = Math.ceil(bitsize/8);
  let maxBinValue = Math.pow(2, bitsize)-1;

  /* In node.js this function fails for bitsize above 32bits */
  if (bitsize > 32)
    throw "number above maximum value";

  /* Conversion to unsigned form based on  */
  if (number < 0)
    number = maxBinValue + number + 1;

  return "0x"+(number >>> 0).toString(16).toUpperCase().padStart(byteCount*2, '0');
}

Тестовий сценарій:

for (let n = 0 ; n < 64 ; n++ ) { 
     let s=decimalToPaddedHexString(-1, n); 
     console.log(`decimalToPaddedHexString(-1,${(n+"").padStart(2)}) = ${s.padStart(10)} = ${("0b"+parseInt(s).toString(2)).padStart(34)}`);
   }

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

decimalToPaddedHexString(-1, 0) =        0x0 =                                0b0
decimalToPaddedHexString(-1, 1) =       0x01 =                                0b1
decimalToPaddedHexString(-1, 2) =       0x03 =                               0b11
decimalToPaddedHexString(-1, 3) =       0x07 =                              0b111
decimalToPaddedHexString(-1, 4) =       0x0F =                             0b1111
decimalToPaddedHexString(-1, 5) =       0x1F =                            0b11111
decimalToPaddedHexString(-1, 6) =       0x3F =                           0b111111
decimalToPaddedHexString(-1, 7) =       0x7F =                          0b1111111
decimalToPaddedHexString(-1, 8) =       0xFF =                         0b11111111
decimalToPaddedHexString(-1, 9) =     0x01FF =                        0b111111111
decimalToPaddedHexString(-1,10) =     0x03FF =                       0b1111111111
decimalToPaddedHexString(-1,11) =     0x07FF =                      0b11111111111
decimalToPaddedHexString(-1,12) =     0x0FFF =                     0b111111111111
decimalToPaddedHexString(-1,13) =     0x1FFF =                    0b1111111111111
decimalToPaddedHexString(-1,14) =     0x3FFF =                   0b11111111111111
decimalToPaddedHexString(-1,15) =     0x7FFF =                  0b111111111111111
decimalToPaddedHexString(-1,16) =     0xFFFF =                 0b1111111111111111
decimalToPaddedHexString(-1,17) =   0x01FFFF =                0b11111111111111111
decimalToPaddedHexString(-1,18) =   0x03FFFF =               0b111111111111111111
decimalToPaddedHexString(-1,19) =   0x07FFFF =              0b1111111111111111111
decimalToPaddedHexString(-1,20) =   0x0FFFFF =             0b11111111111111111111
decimalToPaddedHexString(-1,21) =   0x1FFFFF =            0b111111111111111111111
decimalToPaddedHexString(-1,22) =   0x3FFFFF =           0b1111111111111111111111
decimalToPaddedHexString(-1,23) =   0x7FFFFF =          0b11111111111111111111111
decimalToPaddedHexString(-1,24) =   0xFFFFFF =         0b111111111111111111111111
decimalToPaddedHexString(-1,25) = 0x01FFFFFF =        0b1111111111111111111111111
decimalToPaddedHexString(-1,26) = 0x03FFFFFF =       0b11111111111111111111111111
decimalToPaddedHexString(-1,27) = 0x07FFFFFF =      0b111111111111111111111111111
decimalToPaddedHexString(-1,28) = 0x0FFFFFFF =     0b1111111111111111111111111111
decimalToPaddedHexString(-1,29) = 0x1FFFFFFF =    0b11111111111111111111111111111
decimalToPaddedHexString(-1,30) = 0x3FFFFFFF =   0b111111111111111111111111111111
decimalToPaddedHexString(-1,31) = 0x7FFFFFFF =  0b1111111111111111111111111111111
decimalToPaddedHexString(-1,32) = 0xFFFFFFFF = 0b11111111111111111111111111111111
Thrown: 'number above maximum value'

Примітка. Не надто впевнений, чому він не працює вище 32 біт


-3

Ось моє рішення:

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

Питання говорить: "Як перетворити десятковий в шістнадцятковий у JavaScript" . Хоча питання не вказує, що шістнадцятковий рядок повинен починатися з префікса 0x, кожен, хто пише код, повинен знати, що 0x додається до шістнадцяткових кодів, щоб відрізняти шістнадцяткові коди від програмних ідентифікаторів та інших чисел (1234 може бути шістнадцятковим, десятковим або навіть вісімковий).

Тому, щоб правильно відповісти на це питання, для написання сценарію потрібно додати префікс 0x.

Функція Math.abs (N) перетворює негативи на позитиви, і як бонус, це не схоже на те, що хтось провів її через дроворуб.

Я відповів, що хотів, мав би специфікатор ширини поля, тому ми могли б, наприклад, показати 8/16/32/64-бітні значення, як ви їх бачили в списку шістнадцяткових програм редагування. Це справжня правильна відповідь.


1
У загальній практиці кодування будь-яка алфавітно-числова послідовність, що починається з літери, НЕ ЧИСЛО. Наприклад: ABCDEF012345678 є дійсним ідентифікатором майже в кожній мові кодування на планеті.
Hypersoft Systems

1
О, і префікс 0x не є проблемою для javascript: Number('0xFF') === 255;для всіх, хто там працює, хто хоче зворотну операцію.
Hypersoft Systems
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.