วิธีการแปลงทศนิยมให้เป็นเลขฐานสิบหกใน JavaScript


1479

คุณจะแปลงค่าทศนิยมให้เทียบเท่าเลขฐานสิบหกใน JavaScript ได้อย่างไร


7
เพียงแค่คำเตือนที่นี่ซึ่งคุณกำลังเริ่มต้นจากการเป็นตัวแทนสตริงมันง่ายที่จะสูญเสียความแม่นยำเมื่อคุณเปลี่ยนมันให้เป็น Number ซึ่งเป็นส่วนหนึ่งของการแปลงเป็นเลขฐานสิบหก ดูdanvk.org/wp/2012-01-20/...
studgeek

ฟังก์ชั่นนี้เป็นสิ่งที่คุณต้องการ
Mohammad Musavi

คำตอบ:


2474

แปลงตัวเลขให้เป็นสตริงเลขฐานสิบหกด้วย:

hexString = yourNumber.toString(16);

และย้อนกลับกระบวนการด้วย:

yourNumber = parseInt(hexString, 16);

42
yourNum เป็นสตริงฐานสิบหกในกรณีนี้ เช่น (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul

8
@ สำหรับคุณจะไม่ "หลวมความแม่นยำ" ถ้าคุณแปลงหมายเลขจาวาสคริปต์ (นั่นคือวัตถุหมายเลขซึ่งในสคริปต์ ECMA คือ Double) เป็นฐานสิบหกและย้อนกลับโดยใช้เทคนิคนี้ คำถามที่คุณเชื่อมโยงนั้นมีการอ้างอิงตัวเลขที่มีขนาดใหญ่เกินไปที่จะใส่ลงใน Double ได้อย่างสมบูรณ์ (ดังนั้นการแสดงสตริงในคำถาม) หากคุณมีหมายเลขแล้วจะใช้งานได้ หากคุณมีสิ่งที่ใหญ่เกินไปที่จะเป็นวัตถุหมายเลขจาวาสคริปต์ (เป็นสองเท่า) ดังนั้นคุณจะต้องค้นหาอย่างอื่น
Prestaul

12
@ ดีเร็กฉันมีปัญหาทางด้านจิตใจที่จะไม่ยอมให้ฉันยอมรับวงเล็บที่ไม่จำเป็น ... @ every-else yourNumberเป็นตัวแปร ถ้าคุณต้องการใช้ตัวอักษรที่เป็นตัวเลขคุณจะต้องทำสิ่งที่ชอบ(45).toString(16)แต่ถ้าคุณเขียนโค้ดยากแล้วเขียนมันเป็นสตริงฐานสิบหกด้วยตัวคุณเอง ... (45).toString(16)จะเท่ากันเสมอ'2d'ดังนั้นอย่าเสียซีพียู รอบที่จะคิดออก
Prestaul

21
@Prestaul "อย่าเสีย cpu รอบเพื่อหาว่า" - ที่เรียกว่าการเพิ่มประสิทธิภาพก่อนวัยอันควร ยกเว้นว่าจาวาสคริปต์ทำงานบน 286 ฉันสงสัยเรื่องค่าใช้จ่าย นอกจากนี้ '45' อาจเป็นเลขอาถรรพ์ที่โปรแกรมเมอร์ต้องการเพื่อให้สามารถจดจำ (เช่นระยะเวลาหมดเวลาเป็นวินาที) ในขณะที่ '2d' ใครจะจำได้บ้าง
Dejay Clayton

47
หากคุณไม่ชอบวงเล็บคุณสามารถใช้จุดพิเศษ:42..toString(16)
Thomas Watson

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
นั่นคือส่วนประกอบสองอย่างหรือไม่
Julian

2
ปกติการแปลงนี้ไม่จำเป็นเนื่องจาก JavaScript สามารถแสดงเขตข้อมูล 32 บิตทั้งหมดเป็นตัวเลขที่ไม่ได้ลงชื่อ (ดูที่ Number.MAX_SAFE_INTEGER) ด้วยเหตุผลเดียวกันการแปลงเป็น unsigned สามารถเขียนเป็น:number = 0x100000000 + number;
โยฮันเนส Matokic

3
หมายเหตุสั้น ๆ เกี่ยวกับความคิดเห็นก่อนหน้าของฉัน: ในขณะที่การแสดงเลขฐานสิบหกควรใช้กับตัวเลขได้สูงสุด Number.MAX_SAFE_INTEGER สิ่งนี้ไม่ถือเป็นการดำเนินการระดับบิต (ซึ่งมักใช้ในการสร้างสี 32 บิต) ผลลัพธ์ของการดำเนินการระดับบิตจะเป็นจำนวนเต็ม 32 บิตที่เซ็นชื่อเสมอ ดังนั้นผลลัพธ์ bitwise> = 2 ^ 31 เป็นค่าลบและ 0x100000000 | 0 === 0.
โยฮันเนสมาโตคิค

25
คุณสามารถใช้>>>ประกอบการแปลงจำนวนที่จะได้รับการรับรองการเป็นตัวแทนเช่นผลตอบแทน((-3253) >>> 0).toString(16) "fffff34b"
csharpfolk

1
+1สำหรับการเพิ่มที่มีประโยชน์ แต่ถ้าคุณแปลงตัวเลขเป็นสัญกรณ์ที่แตกต่างกันตัวเลขทั้งหมดนั้นเป็น "ปกติ" เป็นบวกอยู่แล้วหรืออย่างอื่นที่คุณต้องการผลลัพธ์เชิงลบ
คาร์ลสมิ ธ

82

รหัสด้านล่างจะแปลงค่าทศนิยม 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;
}

5
สิ่งนี้จะไม่จัดการค่าลบอย่างเหมาะสม decimalToHex (-6, 4) จะส่งคืน 00-6
JonMR

3
นอกจากนี้ยังมีปัญหากับการลอย แต่การใส่ Math.round () แก้ไขว่า (+1 แล้ว)
Michael - Where's Clay Shirky

ฉันกำลัง "ดึง" ตัวเลขจากอาร์เรย์ ('255,0,55' ฯลฯ ) และ. toString (16) ไม่ทำงาน ทั้งหมดที่ฉันได้รับเป็นตัวเลขเดียวกัน! ฉันได้เพิ่มฟังก์ชั่น "หมายเลข" ไว้ที่ด้านหน้าและตอนนี้ก็ใช้งานได้แล้ว! ใช้เวลาประมาณสี่ชั่วโมงเท่านั้นในการพยายามหาทางแก้ปัญหา !!
Cristofayre

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); }
Lori

2
ไม่ใช่เรื่องยากที่จะขยายออกไปคุณกำลังตัดเลขหลักสุดท้ายด้วย. slice (-number) ตรงนั้น ถ้าคุณเพิ่มค่าศูนย์ที่ด้านหน้ามันจะทำงานได้ดี
Tatarize

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

39

เพื่อความสมบูรณ์ถ้าคุณต้องการtwo's-เติมเต็มการแสดงเลขฐานสิบหกจำนวนลบคุณสามารถใช้กะศูนย์เติมขวา>>>ประกอบการ ตัวอย่างเช่น

> (-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 บิตสับของอักขระสองตัวแรก (FF พิเศษ) -((-2)>>>0).toString(16).substring(2)
23490

36

ด้วยการขยาย:

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

2
@Lucas มันส่งกลับอักขระ 4 ตัวสุดท้าย
Gabriel

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-value-to-hexadecimal (เพิ่มที่#อื่นสำหรับ 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

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 ที่ด้านหน้าของค่า

ดังนั้นสิ่งที่ฉันทำคือเมื่อพิจารณาว่าตัวแปรมีตัวเลข - เพียงแค่แปลงเป็นสตริงและแปลงสตริง ซึ่งหมายความว่าสำหรับทุกคนที่อยู่บนฝั่งเซิร์ฟเวอร์คุณจะต้อง unhex สตริงที่เข้ามาและจากนั้นเพื่อตรวจสอบข้อมูลที่เข้ามาเป็นตัวเลข คุณสามารถทำได้อย่างง่ายดายเพียงแค่เพิ่ม "#" ที่ด้านหน้าของตัวเลขและ "A" ที่ด้านหน้าของสตริงอักขระที่กลับมา ดูฟังก์ชัน toHex ()

มีความสุข!

หลังจากผ่านไปหนึ่งปีและคิดมากฉันตัดสินใจว่าฟังก์ชั่น "toHex" (และฉันยังมีฟังก์ชั่น "fromHex") ที่จำเป็นต้องได้รับการปรับปรุงใหม่ คำถามทั้งหมดคือ "ฉันจะทำสิ่งนี้ให้มีประสิทธิภาพมากขึ้นได้อย่างไร" ฉันตัดสินใจว่า a ถึง / จากฟังก์ชันเลขฐานสิบหกไม่ควรสนใจว่าสิ่งที่เป็นส่วนที่เป็นเศษส่วน แต่ในเวลาเดียวกันก็ควรตรวจสอบให้แน่ใจว่าส่วนที่เป็นเศษส่วนนั้นรวมอยู่ในสตริง

ดังนั้นคำถามจึงกลายเป็น "คุณรู้ได้อย่างไรว่าคุณทำงานกับสตริงเลขฐานสิบหก?" คำตอบนั้นง่าย ใช้ข้อมูล pre-string มาตรฐานที่ได้รับการยอมรับทั่วโลก

ในคำอื่น ๆ - ใช้ "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;

?>

เนื่องจากจาวาสคริปต์ทำงานในส่วนที่เกี่ยวกับฟังก์ชัน toString () ปัญหาเหล่านี้จะถูกกำจัดซึ่งก่อนหน้านี้ก่อให้เกิดปัญหา ตอนนี้สตริงและตัวเลขทั้งหมดสามารถแปลงได้อย่างง่ายดาย นอกจากนี้สิ่งต่าง ๆ เช่นวัตถุจะทำให้เกิดข้อผิดพลาดที่จะสร้างขึ้นโดย JavaScript เอง ฉันเชื่อว่านี่เป็นเรื่องดีเท่าที่จะได้รับ การปรับปรุงที่เหลือเพียงอย่างเดียวคือสำหรับ W3C ที่จะรวมฟังก์ชัน toHex () และ fromHex () ใน JavaScript


ฉันคิดว่าคุณยังมีงานต้องทำที่นี่ ... if( s.substr(0,2)ก่อนif (typeof s != "string")อาจไม่ใช่สิ่งที่คุณต้องการเช่น สิ่งที่ฉันเพิ่งกลับมาไม่ได้เป็นสิ่งที่ผมคาดว่าอย่างใดอย่างหนึ่ง ( toHex(0x1f635)ให้"0x313238353635") ยังไม่ได้ตรวจสอบเพิ่มเติม
ruffin

ฉันเชื่อว่าคุณไม่ถูกต้อง ตัวอย่างของคุณใช้สตริง hex ซึ่งไม่ใช่สตริง - แต่เป็นตัวเลข ดังนั้น 1f635 จะออกมาในแบบที่มันเป็น หากคุณใส่ "0x1f635" มันจะออกมาแตกต่างกัน (เช่น: รูทีนจะส่งคืนเลขฐานสิบหกที่คุณส่งไปยังรูทีน) :-)
Mark Manning เมื่อ

ประเด็นแรกคือคุณไม่สามารถใช้substr& toLowerCaseบนสตริงที่ไม่ใช่ ... ดังนั้นtypeofความต้องการที่จะมาเร็วกว่านี้หรือถ้าคุณคาดว่าtoHexจะใส่สตริงที่ไม่ใช่คุณควรลบtypeofเช็คทั้งหมด ทำให้รู้สึก? นั่นคือถ้าผมใช้รหัสที่นี่โดยไม่ต้องแก้ไขและเรียกผมได้รับtoHex(0x1f635) Uncaught TypeError: s.substr is not a functionถ้าฉันย้ายการร่ายสตริงก่อนหน้านี้คุณพูดถูกตัวเลขจะถูกแปลงเป็นทศนิยมก่อนบางทีและสิ่งต่าง ๆ จะไปด้านข้าง ซึ่งหมายความว่าคุณไม่สามารถทำการส่งแบบง่าย ๆ ที่นี่หากsไม่ใช่สายอักขระ
ruffin

จริงๆแล้วภายใต้ XP ใช้งานได้ดี มีการอัปเดตจำนวนมากสำหรับ Javascript ซึ่งทำให้ Javascript เป็น typecast ซึ่งจะโยนข้อยกเว้น ภายใต้ XP มัน jusr ทำงาน อย่างน้อยสำหรับฉัน ในโลกของ typecast - การใส่ "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}" มีความเหมาะสม แต่ ox1f635 ยังไม่เป็นสตริง :-)
Mark Manning


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-elementของ CSS คุณสมบัติการcolorrgb(64, 62, 154)


10

จำกัด / เสริมจำนวนอักขระที่กำหนด:

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

2
วิธีนี้จะแปลงตัวเลขให้เป็นเลขฐานสิบหกและนำหน้าศูนย์แผ่นนี้สวยงาม!
Gordon

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 ไม่ใช่ว่าทุกสคริปต์จะต้องทำงานในล่ามเถื่อนดั้งเดิม แต่ก็มี Babel ด้วยเช่นกัน และสุดท้าย ES6 นั้นชัดเจนมากขึ้นถ้าคุณรู้ ที่กล่าวว่าการให้คำตอบมาตรฐาน JS สามารถช่วยผู้คนได้มากขึ้น แต่การพิจารณาว่ามีคำตอบอื่น ๆ สำหรับรุ่นเก่าของ JS การมีคำตอบ ES6 เป็นเพียงประโยชน์เท่านั้น "นี่คือสิ่งที่ฉันทำได้ในวันนี้"
WiR3D

Minnesons ไม่ได้ให้ข้อเท็จจริงดังนั้น "การโต้แย้ง" ของคุณจึงไม่ถูกต้อง @ WiR3D
ระบบ

@HypersoftSystems มันก็ใช้ได้เหมือนของคุณถ้าไม่มากนักเนื่องจากคุณมีความคิดเห็นและ จำกัด บริบทของบริบทที่อาจไม่ถูกต้องในแอปพลิเคชั่นที่ทันสมัยที่สุด
WiR3D

ข้อผิดพลาดของผู้ใช้: "เหมือนกับความคิดเห็น", "น่าจะ" และ "มากที่สุด"
ระบบ

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-style) คุณสามารถก้าวเท้าเลี่ยงปัญหาทั้งหมดโดยการเขียนโดยcolor: rgb(r,g,b)ที่ rg และ b เป็นเลขทศนิยม
telent

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 }
Aykut Çevik

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 = 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;
}

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)

Simple .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
โอ้ ... นี่เป็นวิธีที่น่ากลัวและน่ากลัวจริง ๆ ในรูปแบบการเข้ารหัสที่น่าเกลียด สุจริต: เกิดอะไรขึ้นกับการขึ้นบรรทัดใหม่และการเยื้อง ตัวแปรตัวอักษรเดียว? จริงๆ?
Victor Schröder

1
ปรับปรุงใหม่ วิธีนี้น่ากลัวหรือไม่? และสไตล์ที่ดีกว่าคืออะไร ?? ตอนแรกฉันคิดว่ามันจะง่ายกว่าที่จะเข้าใจในทุกขั้นตอน "ตัวอักษร" ที่สะกดออกมาเช่นนั้นด้วยตัวอักษร ... บางครั้งฉันก็โง่ได้
JonLikeSquirrel

4
ขออภัยใช่ยังคงแย่มาก รหัสของคุณยังใช้ลูปที่ไม่มีประสิทธิภาพจำนวนมากและสร้างมลภาวะให้กับเนมสเปซส่วนกลางรวมถึงปัญหาอื่น ๆ วิธีการของตัวเองมากเกินไปสำหรับงานที่สามารถทำได้โดยการเรียกฟังก์ชัน หากคุณต้องการที่จะปรับปรุงรูปแบบการเข้ารหัสของคุณใน JS ผมขอแนะนำให้คุณไปอ่านเนื้อหาเช่นw3.org/wiki/JavaScript_best_practicesและgoogle.github.io/styleguide/javascriptguide.xml เพียง google เกี่ยวกับเรื่อง
Victor Schröder

1
ฉันทำการทดสอบความเร็วใน Chrome และฟังก์ชั่น overkill ของฉันเร็วกว่า. toString (16) ประมาณ 30% ในขณะที่ใน Firefox ฟังก์ชั่นของฉันช้ากว่า 40% ถึง. toString (16) ... Chrome พิสูจน์ว่าลูปที่มากเกินไปนั้นมีประสิทธิภาพมากกว่า มากกว่าฟังก์ชั่น. toString (16) ของเบราว์เซอร์ในขณะที่ Firefox พิสูจน์ได้ว่าทำไมผู้คนถึงชอบ Chrome มากกว่า หรือว่าถอยหลัง วันหนึ่ง Chrome อาจอัพเดตเป็น. toString (16) ที่เร็วขึ้นทำให้ฉันผิดทั้งสองกรณี! ฉันไม่ผิดอย่างสมบูรณ์และไม่ถูกต้องทั้งหมดของคุณ อัตตาของฉันกันฉันจะได้รับคะแนนของคุณอย่างน้อย 30% ของมัน ;)
JonLikeSquirrel

2
คุณไม่จำเป็นต้องประกาศอาร์เรย์ของสตริงที่มีอักขระเดี่ยวแต่ละตัว เพียงประกาศสตริงอักขระ คุณสามารถรับตัวละครจากสตริงเช่นเดียวกับที่คุณทำกับอาร์เรย์โดยใช้วงเล็บเหลี่ยม
David Spector

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

หากคุณกำลังมองหาการแปลงจำนวนเต็มขนาดใหญ่เช่นตัวเลขที่มากกว่า Number.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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.