كيفية تحويل النظام العشري إلى النظام الست عشري في جافا سكريبت

StackOverflow https://stackoverflow.com/questions/57803

سؤال

كيف يمكنك تحويل القيم العشرية إلى ما يعادلها الست عشري في جافا سكريبت؟

هل كانت مفيدة؟

المحلول

تحويل رقم إلى سلسلة سداسية عشرية باستخدام:

hexString = yourNumber.toString(16);

وعكس العملية مع:

yourNumber = parseInt(hexString, 16);

نصائح أخرى

إذا كنت بحاجة إلى التعامل مع أشياء مثل حقول البت أو الألوان 32 بت، فأنت بحاجة إلى التعامل مع الأرقام الموقعة.وظيفة جافا سكريبت toString(16) سيُرجع رقمًا سداسيًا عشريًا سالبًا وهو عادةً ليس ما تريده.تقوم هذه الوظيفة ببعض الإضافات المجنونة لجعلها رقمًا موجبًا.

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

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

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

سيقوم الكود أدناه بتحويل القيمة العشرية d إلى الست عشري.كما يسمح لك بإضافة الحشو إلى النتيجة السداسية العشرية.لذلك سيصبح 0 00 افتراضيًا.

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

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

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

مع الحشو:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}

للاستكمال، إذا كنت تريد متمم ثنائي تمثيل سداسي عشري لرقم سالب، يمكنك استخدام التحول صفر ملء اليمين >>> المشغل أو العامل.على سبيل المثال:

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

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

ولكن هناك قيد واحد: تتعامل عوامل تشغيل JavaScript المتعلقة بالبت مع معاملاتها كتسلسل مكون من 32 بت, ، أي أنك تحصل على تكملة 32 بت ثنائية.

بدون الحلقة:

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

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

أليس من الأفضل أيضًا عدم استخدام اختبارات الحلقة التي يجب تقييمها؟

على سبيل المثال، بدلاً من:

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

يملك

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

الجمع بين بعض هذه الأفكار الجيدة لوظيفة قيمة RGB إلى الست عشري (أضف ملف # في مكان آخر لـ HTML/CSS):

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

لم تأخذ الإجابة المقبولة في الاعتبار الرموز السداسية العشرية التي تم إرجاعها والتي تحتوي على رقم واحد.يتم تعديل ذلك بسهولة عن طريق:

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

و

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

    return a;
}

أعتقد أن الإجابات المذكورة أعلاه قد تم نشرها عدة مرات من قبل الآخرين بشكل أو بآخر.أقوم بلفها في دالة toHex() كما يلي:

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

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

لاحظ أن التعبير العادي الرقمي جاء من 10+ وظائف مفيدة للتعبير العادي في JavaScript لتحسين كفاءة تطبيقات الويب لديك.

تحديث:بعد اختبار هذا الشيء عدة مرات وجدت خطأ (علامات الاقتباس المزدوجة في RegExp)، لذلك أصلحت ذلك.لكن!بعد إجراء قدر كبير من الاختبار وقراءة منشور ألماز - أدركت أنني لا أستطيع الحصول على أرقام سلبية للعمل.

علاوة على ذلك - لقد قمت ببعض القراءة حول هذا الأمر وبما أن جميع أرقام 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 ().تحويل سلسلة ASCII إلى النظام الست عشري.////////////////////////////////////////////////////////////// ////////////////////////////////وق ") { عائدات؛}

    var l = "0123456789ABCDEF";
    var o = "";

    if (typeof s != "string") {
        s = s.toString();
    }
    for (var i=0; i<s.length; i++) {
        var c = s.charCodeAt(i);

        o = o + l.substr((c>>4),1) + l.substr((c & 0x0f),1);
    }

    return "0x" + o;
}

هذه وظيفة سريعة جدًا تأخذ في الاعتبار الأرقام الفردية وأرقام الفاصلة العائمة، وتتحقق أيضًا لمعرفة ما إذا كان الشخص يرسل قيمة سداسية عشرية ليتم ربطها مرة أخرى.يستخدم فقط أربعة استدعاءات للوظائف، اثنان منها فقط موجودان في الحلقة.لإلغاء تحديد القيم التي تستخدمها:

/////////////////////////////////////////////////////////////////////////////
//  fromHex().  Convert a hex string to ASCII text.
/////////////////////////////////////////////////////////////////////////////
fromHex(s)
{
    var start = 0;
    var o = "";

    if (s.substr(0,2) == "0x") {
        start = 2;
    }

    if (typeof s != "string") {
        s = s.toString();
    }
    for (var i=start; i<s.length; i+=2) {
        var c = s.substr(i, 2);

        o = o + String.fromCharCode(parseInt(c, 16));
    }

    return o;
}

مثل الدالة toHex()، تبحث الدالة fromHex() أولاً عن "0x" ثم تقوم بترجمة المعلومات الواردة إلى سلسلة إذا لم تكن سلسلة بالفعل.لا أعرف كيف لن تكون سلسلة - ولكن فقط في حالة - أتحقق منها.تقوم الوظيفة بعد ذلك بالتقاط حرفين وترجمتهما إلى أحرف ASCII.إذا كنت تريد ترجمة Unicode، فستحتاج إلى تغيير الحلقة بحيث تتم بأربعة (4) أحرف في المرة الواحدة.ولكن عليك أيضًا التأكد من أن السلسلة غير قابلة للقسمة على أربعة.إذا كان كذلك - فهو عبارة عن سلسلة سداسية عشرية قياسية.(تذكر أن السلسلة تحتوي على "0x" في مقدمتها.)

برنامج نصي اختباري بسيط لإظهار أن -3.14159265، عند تحويله إلى سلسلة، لا يزال -3.14159265.

<?php

    echo <<<EOD
<html>
    <head><title>Test</title>
        <script>
            var a = -3.14159265;
            alert( "A = " + a );
            var b = a.toString();
            alert( "B = " + b );
        </script>
    </head>
    <body>
    </body>
</html>
EOD;

?>

نظرًا لكيفية عمل JavaScript فيما يتعلق بوظيفة toString()، يمكن التخلص من كل تلك المشكلات التي كانت تسبب مشكلات من قبل.الآن يمكن تحويل جميع السلاسل والأرقام بسهولة.علاوة على ذلك، فإن أشياء مثل الكائنات ستتسبب في إنشاء خطأ بواسطة JavaScript نفسها.أعتقد أن هذا جيد بقدر ما يحصل.التحسين الوحيد المتبقي هو أن يقوم W3C فقط بتضمين دالة toHex() وfromHex() في JavaScript.

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

16 هو الجذر وهناك 16 قيمة في رقم سداسي عشري :-)

مقيدة/مبطنة لعدد محدد من الأحرف:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
function dec2hex(i)
{
  var result = "0000";
  if      (i >= 0    && i <= 15)    { result = "000" + i.toString(16); }
  else if (i >= 16   && i <= 255)   { result = "00"  + i.toString(16); }
  else if (i >= 256  && i <= 4095)  { result = "0"   + i.toString(16); }
  else if (i >= 4096 && i <= 65535) { result =         i.toString(16); }
  return result
}

إذا كنت تريد تحويل رقم إلى تمثيل سداسي عشري لقيمة لون RGBA، فقد وجدت أن هذا هو المزيج الأكثر فائدة من عدة نصائح من هنا:

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

بقدر ما أعلم تعليق 57807 غير صحيح ويجب أن يكون شيء من هذا القبيل:var hex = Number(d).toString(16);بدلاً منvar hex = parseInt(d, 16);

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

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

    return hex;
}

لكل من يهمه الأمر، إليك JSFiddle يقارن معظم الإجابات المقدمة على هذا السؤال.

وإليك الطريقة التي انتهى بي الأمر بها:

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

ضع في اعتبارك أيضًا أنه إذا كنت تتطلع إلى التحويل من النظام العشري إلى النظام العشري لاستخدامه في CSS كملف نوع بيانات اللون, ، قد تفضل بدلاً من ذلك استخراج قيم RGB من العلامة العشرية واستخدامها rgb().

على سبيل المثال (JSFiddle):

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

// assuming you're using jQuery...
$("#some-element").css("color", "rgb(" + rgb + ")");

هذا يحدد #some-elementCSS color الملكية ل rgb(64, 62, 154).

إليك نسخة مختصرة من ECMAScript 6:

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

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

وإذا كان الرقم سلبيا؟

هنا هو الإصدار الخاص بي.

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

يمكنك التحقق مما يلي مثال JsFiddle أو مثال لرمز Stack Overflow JavaScript أيضًا.

'use strict';

var convertBase = function () {

    function convertBase(baseFrom, baseTo) {
        return function (num) {
            return parseInt(num, baseFrom).toString(baseTo);

        };
    }

    // Decimal to hexadecimal
    convertBase.dec2hex = convertBase(10, 16);
    return convertBase;
}();

alert(convertBase.dec2hex('42')); // '2a'

أقوم بالتحويل إلى سلسلة سداسية في حلقة كبيرة جدًا، لذا جربت عدة تقنيات للعثور على أسرعها.كانت متطلباتي هي الحصول على سلسلة ذات طول ثابت نتيجة لذلك، وترميز القيم السالبة بشكل صحيح (-1 => ff..f).

بسيط .toString(16) لم ينجح الأمر بالنسبة لي لأنني كنت بحاجة إلى تشفير القيم السالبة بشكل صحيح.الكود التالي هو الأسرع الذي اختبرته حتى الآن على قيم 1-2 بايت (لاحظ ذلك symbols يحدد عدد رموز الإخراج التي تريد الحصول عليها، أي أنه بالنسبة لعدد صحيح مكون من 4 بايت يجب أن يساوي 8):

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

يؤدي أداء أسرع من .toString(16) على أرقام 1-2 بايت وأبطأ على الأعداد الأكبر (متى symbols >= 6)، ولكن لا يزال يتعين عليها أن تتفوق على الأساليب التي تشفر القيم السالبة بشكل صحيح.

كما تنص الإجابة المقبولة، فإن أسهل طريقة للتحويل من النظام العشري إلى النظام الست عشري هي var hex = dec.toString(16).ومع ذلك، قد تفضل إضافة تحويل سلسلة، لأنه يضمن أن تمثيلات السلسلة مثل "12".toString(16) العمل بشكل صحيح.

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

لعكس العملية، يمكنك أيضًا استخدام الحل أدناه، لأنه أقصر.

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

يبدو أنه أبطأ في Google Chrome وFirefox، ولكنه أسرع بشكل ملحوظ في Opera.يرى http://jsperf.com/hex-to-dec.

كيفية تحويل النظام العشري إلى النظام الست عشري في جافا سكريبت

لم أتمكن من العثور على رقم عشري نظيف/بسيط إلى تحويل سداسي عشري لا يتضمن فوضى في الوظائف والمصفوفات ...لذلك كان علي أن أفعل هذا بنفسي.

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

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

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

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

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

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

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

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

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

/* Original: */

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

do {
    ++B;
    A& = C;

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

        case 0xB: A='B'
        break;

        case 0xC: A='C'
        break;

        case 0xD: A='D'
        break;

        case 0xE: A='E'
        break;

        case 0xF: A='F'
        break;

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

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

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

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

لتلخيص كل ذلك؛

function toHex(i, pad) {

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

  var strToParse = i.toString(16);

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

  var finalVal =  parseInt(strToParse, 16);

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

  return finalVal;
}

ومع ذلك، إذا لم تكن بحاجة إلى تحويله مرة أخرى إلى عدد صحيح في النهاية (أي.للألوان)، فالتأكد من أن القيم ليست سلبية سيكون كافيًا.

لم أجد إجابة واضحة، بدون التحقق مما إذا كانت سلبية أو إيجابية، والتي تستخدم مكمل اثنين (الأرقام السالبة متضمنة).لذلك، أعرض الحل الخاص بي لبايت واحد:

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

يمكنك استخدام هذه التعليمات لأي رقم بايت، أنت فقط تضيفه FF في الأماكن المعنية.على سبيل المثال، إلى بايتين:

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

إذا كنت تريد إرسال عدد صحيح من المصفوفة إلى السلسلة السداسية العشرية:

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

في حال كنت تتطلع إلى التحويل إلى تمثيل JavaScript أو CSS "كامل"، يمكنك استخدام شيء مثل:

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

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

يمكنك أن تفعل شيئا مثل هذا في ECMAScript 6:

const toHex = num => (num).toString(16).toUpperCase();

إذا كنت تبحث عن تحويل الأعداد الصحيحة الكبيرة، على سبيل المثال.الأرقام أكبر من Number.MAX_SAFE_INTEGER -- 9007199254740991 فيمكنك استخدام الكود التالي

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

هذا هو الحل الخاص بي:

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

السؤال يقول: "كيفية تحويل النظام العشري إلى النظام الست عشري في جافا سكريبت".في حين أن السؤال لا يحدد أن السلسلة السداسية العشرية يجب أن تبدأ ببادئة 0x، يجب على أي شخص يكتب رمزًا أن يعرف أنه تتم إضافة 0x إلى الرموز السداسية العشرية للتمييز رموز سداسية عشرية من معرفات برمجية و أرقام أخرى (1234 يمكن أن يكون سداسي عشري، عشري، أو حتى ثماني).

ولذلك، للإجابة بشكل صحيح على هذا السؤال، لغرض كتابة السيناريو، يجب عليك إضافة البادئة 0x.

تعمل وظيفة Math.abs(N) على تحويل السلبيات إلى إيجابيات، وكمكافأة، لا يبدو أن شخصًا ما مررها عبر ماكينة تقطيع الخشب.

الإجابة التي أردتها، كانت تحتوي على محدد عرض الحقل، حتى نتمكن على سبيل المثال من عرض قيم 8/16/32/64 بت بالطريقة التي تراها مدرجة في تطبيق تحرير سداسي عشري.تلك هي الإجابة الفعلية والصحيحة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top