Cách chuyển đổi thập phân thành thập lục phân trong JavaScript


1479

Làm cách nào để bạn chuyển đổi giá trị thập phân thành tương đương thập lục phân của chúng trong JavaScript?


7
Chỉ cần một cảnh báo ở đây là bạn đang bắt đầu từ một chuỗi đại diện, rất dễ mất độ chính xác khi bạn biến nó thành Số như một phần của việc chuyển đổi nó thành hex. Xem danvk.org/wp/2012-01-20/ .
studgeek

Đây chức năng là chính xác những gì bạn cần
Mohammad Musavi

Câu trả lời:


2474

Chuyển đổi một số thành một chuỗi thập lục phân với:

hexString = yourNumber.toString(16);

Và đảo ngược quá trình với:

yourNumber = parseInt(hexString, 16);

42
yourNum là một chuỗi hex trong trường hợp này. Ví dụ: (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul

8
@forste, bạn sẽ không "mất độ chính xác" nếu bạn chuyển đổi Số javascript (đó là đối tượng Số, trong tập lệnh ECMA là Double) thành hex và quay lại bằng kỹ thuật này. Câu hỏi bạn liên kết cụ thể là các số tham chiếu quá lớn để khớp với Double (do đó biểu diễn chuỗi trong câu hỏi). Nếu bạn đã có Số thì nó sẽ hoạt động. Nếu bạn có một cái gì đó quá lớn để trở thành một đối tượng Số javascript (Double) thì bạn sẽ phải tìm một thứ khác.
Prestaul

12
@Derek, tôi có một vấn đề tâm lý không cho phép tôi chịu đựng các dấu ngoặc đơn không cần thiết ... @ mọi người khác, yourNumberlà một biến số. Nếu bạn muốn sử dụng một chữ số thì bạn sẽ phải làm một cái gì đó như thế (45).toString(16), nhưng nếu bạn khó mã hóa một số thì xin vui lòng chỉ viết nó dưới dạng một chuỗi hex ... (45).toString(16)sẽ luôn bằng nhau '2d', vì vậy đừng lãng phí cpu chu kỳ để tìm ra điều đó.
Prestaul

21
@Prestaul "Đừng lãng phí chu kỳ cpu để tìm ra điều đó" - đó gọi là tối ưu hóa sớm. Trừ khi JavaScript đang chạy trên một chiếc 286, tôi nghi ngờ các vấn đề trên không. Hơn nữa, '45' có thể là một con số kỳ diệu mà lập trình viên cần để có thể nhận ra (chẳng hạn như thời gian chờ tính bằng giây), trong khi '2d', ai sẽ nhận ra điều đó?
Dejay Clayton

47
Nếu bạn không thích dấu ngoặc đơn, bạn chỉ có thể sử dụng dấu chấm phụ:42..toString(16)
Thomas Watson

142

Nếu bạn cần xử lý những thứ như trường bit hoặc màu 32 bit, thì bạn cần xử lý các số đã ký. Hàm JavaScript toString(16)sẽ trả về số thập lục phân âm thường không phải là số bạn muốn. Hàm này thực hiện một số bổ sung điên để biến nó thành một số dương.

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
đó là hai bổ sung?
Julian

2
Chuyển đổi này thường không cần thiết vì JavaScript có thể biểu thị tất cả các trường bit 32 bit dưới dạng số không dấu (Xem Number.MAX_SAFE_INTEGER). Vì lý do tương tự, việc chuyển đổi thành không dấu có thể được viết là:number = 0x100000000 + number;
Johannes Matokic

3
Một lưu ý ngắn về nhận xét trước đây của tôi: Mặc dù biểu diễn hex nên hoạt động đối với các số lên tới Number.MAX_SAFE_INTEGER nhưng điều này không giữ cho các hoạt động theo bit (thường được sử dụng để tạo màu 32 bit). Kết quả của các phép toán bitwise luôn là một số nguyên 32 bit đã ký. Do đó, kết quả bitwise> = 2 ^ 31 là âm và 0x100000000 | 0 === 0.
Julian Matokic

25
Bạn có thể sử dụng >>>toán tử để chuyển đổi số thành biểu diễn không dấu, ví dụ ((-3253) >>> 0).toString(16)trả về "fffff34b".
csharpfolk 21/07/2015

1
+1đối với một bổ sung hữu ích, nhưng nếu bạn chuyển đổi các số sang một ký hiệu khác, tất cả các số đều "thường" dương hoặc nếu không bạn muốn có kết quả âm.
Carl Smith

82

Mã dưới đây sẽ chuyển đổi giá trị thập phân d thành thập lục phân. Nó cũng cho phép bạn thêm phần đệm vào kết quả thập lục phân. Vì vậy, 0 sẽ trở thành 00 theo mặc định.

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
Điều này sẽ không xử lý đúng các giá trị âm. binaryToHex (-6, 4) sẽ trả về 00-6.
JonMR

3
Nó cũng có vấn đề với float, nhưng đưa vào Math.round () đã khắc phục điều đó. (+ 1ed)
Michael - Trường hợp Clay Shirky

Tôi đang "kéo" các số từ một mảng ('255,0,55', v.v.) và .toString (16) không hoạt động. Tất cả tôi nhận được là những con số giống nhau! Tôi đã thêm chức năng "Số" vào phía trước và bây giờ nó hoạt động! Chỉ dành khoảng bốn giờ cố gắng để tìm giải pháp !!
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
Không khó để mở rộng nó, bạn đang cắt các chữ số cuối cùng với .slice (-số) ở đó. Nếu bạn thêm nhiều số 0 ở phía trước, nó sẽ hoạt động tốt.
Tatarize

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

39

Để đầy đủ, nếu bạn muốn biểu diễn thập lục phân bổ sung của hai số âm, bạn có thể sử dụng toán tử dịch chuyển zero-fill-right>>> . Ví dụ:

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

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

Tuy nhiên, có một hạn chế: Các toán tử bitwise JavaScript xử lý các toán hạng của chúng như một chuỗi 32 bit , nghĩa là bạn có được phần bù hai bit 32 bit.


2
đây là câu trả lời có giá trị nhất cho câu hỏi này :)
albertjan

Đi sâu vào tất cả các câu hỏi vì C# number to hexadecimalđã tạo ra kết quả khác nhau Javascript number to hexadecimal. Có vẻ như Javascript có vấn đề với số âm. Câu trả lời này dường như là giải pháp cho vấn đề.
goamn

Điều này là rất hữu ích, cảm ơn bạn! Tôi đã sử dụng điều này cho các màu RGB, vì vậy để có được biến thể 24 bit, hãy cắt hai ký tự đầu tiên (FF phụ) -((-2)>>>0).toString(16).substring(2)
antonyh

36

Với phần đệm:

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

2
@Lucas Nó trả về 4 ký tự cuối cùng.
Gabriel

19

Không có vòng lặp:

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

Ngoài ra, tốt hơn hết là không sử dụng các bài kiểm tra vòng lặp phải được đánh giá?

Ví dụ: thay vì:

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

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

19

Kết hợp một số ý tưởng hay này cho hàm RGB-value-to-hexadecimal (thêm các vị trí #khác cho 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);
}

Cám ơn vì cái này! Tôi cố gắng để bình luận một thời gian dài trước đây. Đó là chìa khóa cho câu trả lời của tôi. stackoverflow.com/questions/5560248/
Pimp Trizkit

16

Câu trả lời được chấp nhận không đưa vào tài khoản một chữ số trả về mã thập lục phân. Điều này dễ dàng được điều chỉnh bởi:

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

Tôi tin rằng các câu trả lời trên đã được đăng bởi nhiều người dưới hình thức này hay hình thức khác. Tôi gói chúng trong hàm toHex () như vậy:

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

Lưu ý rằng biểu thức chính quy số đến từ 10+ Hàm biểu thức chính quy JavaScript hữu ích để cải thiện hiệu quả ứng dụng web của bạn .

Cập nhật: Sau khi kiểm tra điều này nhiều lần tôi đã tìm thấy một lỗi (dấu ngoặc kép trong RegExp), vì vậy tôi đã sửa nó. TUY NHIÊN! Sau khá nhiều thử nghiệm và đã đọc bài đăng của almaz - tôi nhận ra rằng tôi không thể có được số âm để làm việc.

Hơn nữa - Tôi đã đọc một số điều này và vì tất cả các số JavaScript được lưu trữ dưới dạng các từ 64 bit cho dù thế nào - tôi đã thử sửa đổi mã numHex để có được từ 64 bit. Nhưng hóa ra bạn không thể làm điều đó. Nếu bạn đặt "3.14159265" NHƯ MỘT SỐ vào một biến - tất cả những gì bạn có thể nhận được là "3", vì phần phân số chỉ có thể truy cập bằng cách nhân số đó với mười (IE: 10.0) nhiều lần. Hoặc nói theo cách khác - giá trị thập lục phân 0xF làm cho giá trị dấu phẩy động được dịch thành một số nguyên trước khi ANDed loại bỏ mọi thứ phía sau dấu chấm . Thay vì lấy toàn bộ giá trị (ví dụ: 3.14159265) và ANDing giá trị dấu phẩy động so với giá trị 0xF.

Vì vậy, điều tốt nhất để làm, trong trường hợp này là chuyển đổi 3.14159265 thành một chuỗi và sau đó chỉ cần chuyển đổi chuỗi. Do những điều trên, nó cũng giúp bạn dễ dàng chuyển đổi các số âm vì dấu trừ chỉ trở thành 0x26 ở mặt trước của giá trị.

Vì vậy, những gì tôi đã làm là xác định rằng biến chứa một số - chỉ cần chuyển đổi nó thành một chuỗi và chuyển đổi chuỗi. Điều này có nghĩa với tất cả mọi người rằng về phía máy chủ, bạn sẽ cần mở chuỗi chuỗi đến và sau đó để xác định thông tin đến là số. Bạn có thể làm điều đó một cách dễ dàng bằng cách chỉ cần thêm "#" vào phía trước các số và "A" ở phía trước chuỗi ký tự quay lại. Xem hàm toHex ().

Chúc vui vẻ!

Sau một năm nữa và suy nghĩ rất nhiều, tôi quyết định rằng hàm "toHex" (và tôi cũng có chức năng "fromHex") thực sự cần phải được tân trang lại. Toàn bộ câu hỏi là "Làm thế nào tôi có thể làm điều này hiệu quả hơn?" Tôi đã quyết định rằng một hàm đến / từ thập lục phân không nên quan tâm nếu một cái gì đó là một phần phân số nhưng đồng thời nó phải đảm bảo rằng các phần phân số được bao gồm trong chuỗi.

Vì vậy, sau đó câu hỏi trở thành, "Làm thế nào để bạn biết bạn đang làm việc với một chuỗi thập lục phân?". Đáp án đơn giản. Sử dụng thông tin tiền chuỗi tiêu chuẩn đã được công nhận trên toàn thế giới.

Nói cách khác - sử dụng "0x". Vì vậy, bây giờ hàm toHex của tôi trông để xem nếu nó đã ở đó và nếu có - nó chỉ trả về chuỗi đã được gửi đến nó. Nếu không, nó chuyển đổi chuỗi, số, bất cứ điều gì. Đây là chức năng toHex được sửa đổi:

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

Đây là một hàm rất nhanh có tính đến các chữ số đơn, số dấu phẩy động và thậm chí kiểm tra xem liệu người đó có gửi một giá trị hex qua để được lục lại không. Nó chỉ sử dụng bốn lệnh gọi hàm và chỉ hai trong số chúng nằm trong vòng lặp. Để bỏ hex các giá trị bạn sử dụng:

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

Giống như hàm toHex (), hàm fromHex () trước tiên tìm "0x" và sau đó nó dịch thông tin đến thành một chuỗi nếu nó chưa phải là một chuỗi. Tôi không biết làm thế nào nó sẽ không phải là một chuỗi - nhưng chỉ trong trường hợp - tôi kiểm tra. Hàm sau đó đi qua, lấy hai ký tự và dịch chúng sang các ký tự ASCII. Nếu bạn muốn nó dịch Unicode, bạn sẽ cần thay đổi vòng lặp thành bốn (4) ký tự cùng một lúc. Nhưng sau đó, bạn cũng cần đảm bảo rằng chuỗi KHÔNG chia hết cho bốn. Nếu có - thì đó là một chuỗi thập lục phân chuẩn. (Hãy nhớ chuỗi có "0x" ở mặt trước của chuỗi.)

Một tập lệnh thử nghiệm đơn giản để chỉ ra rằng -3,14159265, khi được chuyển đổi thành một chuỗi, vẫn là -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;

?>

Do cách JavaScript hoạt động liên quan đến hàm toString (), tất cả các vấn đề đó có thể được loại bỏ mà trước đó đã gây ra sự cố. Bây giờ tất cả các chuỗi và số có thể được chuyển đổi dễ dàng. Hơn nữa, những thứ như các đối tượng sẽ gây ra lỗi do chính JavaScript tạo ra. Tôi tin rằng điều này là tốt như nó được. Cải tiến duy nhất còn lại là để W3C chỉ bao gồm hàm toHex () và fromHex () trong JavaScript.


Tôi nghĩ rằng bạn vẫn còn có việc phải làm ở đây ... chẳng hạn, if( s.substr(0,2)trước đây if (typeof s != "string")có lẽ không phải là điều bạn muốn. Những gì tôi đã trả lại không phải là những gì tôi mong đợi ( toHex(0x1f635)cho "0x313238353635"). Chưa điều tra thêm.
ruffin

Tôi tin rằng bạn không chính xác. Ví dụ của bạn đang sử dụng chuỗi hex KHÔNG phải là chuỗi - mà là số. Do đó, 1f635 sẽ xuất hiện như vậy. Nếu bạn đã đặt "0x1f635", nó sẽ xuất hiện khác đi. (tức là: thường trình sẽ trả về số hex bạn đã gửi cho thường trình.) :-)
Mark Manning

Điểm đầu tiên là bạn không thể sử dụng substr& toLowerCasetrên một chuỗi không ... vì vậy, hoặc là typeofcần phải đến sớm hơn, hoặc, nếu bạn dự kiến ​​sẽ toHexném vào một chuỗi không có chuỗi ngay tại đó, bạn nên xóa typeofhoàn toàn kiểm tra. Có lý? Đó là, nếu tôi đã sử dụng mã ở đây mà không cần chỉnh sửa và được gọi toHex(0x1f635), tôi sẽ nhận được Uncaught TypeError: s.substr is not a function. Nếu tôi di chuyển chuỗi được đúc sớm hơn, bạn có thể đúng, số sẽ chuyển sang số thập phân trước, có lẽ và mọi thứ đi ngang. Điều đó tất nhiên có nghĩa là bạn không thể thực hiện một vai đơn giản ở đây nếu skhông phải là một chuỗi.
ruffin

Trên thực tế, dưới XP điều này hoạt động tốt. Đã có một số bản cập nhật cho Javascript đang biến Javascript thành kiểu chữ. Mà sẽ ném một ngoại lệ. Dưới XP nó hoạt động. Ít nhất là đối với tôi. Trong một thế giới typecast - đặt "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}" là phù hợp. Nhưng ox1f635 vẫn không phải là một chuỗi. :-)
Đánh dấu Manning

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

16 là cơ số và có 16 giá trị trong một số thập lục phân :-)


12

Đối với bất kỳ ai quan tâm, đây là một JSFiddle so sánh hầu hết các câu trả lời cho câu hỏi này .

Và đây là phương pháp tôi đã thực hiện:

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

Ngoài ra, hãy nhớ rằng nếu bạn đang muốn chuyển đổi từ thập phân sang hex để sử dụng trong CSS làm kiểu dữ liệu màu , thay vào đó, bạn có thể thích trích xuất các giá trị RGB từ thập phân và sử dụng rgb () .

Ví dụ: ( 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 + ')')

Đây bộ #some-elementCSS của colortài sản để rgb(64, 62, 154).


10

Ràng buộc / đệm vào một số ký tự đã đặt:

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

2
Điều này chuyển đổi một số thành một chuỗi hex và các số 0 hàng đầu, điều này thật đẹp!
Gordon

10

Đây là phiên bản ECMAScript 6 được cắt bớt:

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'

Rất không đồng ý với @HypersoftSystems, nếu môi trường hoặc tình huống của bạn liên quan đến bạn, thì hãy sử dụng ES6. Không phải mọi kịch bản cần phải chạy trong các trình thông dịch bootleg kế thừa, cũng có babel tồn tại vì một lý do. Và cuối cùng, ES6 dễ đọc hơn nếu bạn biết điều đó. Điều đó nói rằng việc đưa ra các câu trả lời JS tiêu chuẩn có thể giúp nhiều người hơn nhưng việc xem xét có các câu trả lời khác cho các phiên bản JS cũ hơn, có câu trả lời ES6 chỉ có lợi, "đây là cách tôi đã làm lại từ đầu".
WiR3D

Opinons không đưa ra sự thật, do đó "đối số" của bạn không hợp lệ. @ WiR3D
Hệ thống Hypersoft

@HypersoftSystems không hợp lệ như của bạn nếu không phải như vậy, vì hệ thống của bạn cũng giống như ý kiến ​​và giới hạn bối cảnh trong bối cảnh có thể không hợp lệ trong hầu hết các ứng dụng hiện đại.
WiR3D

lỗi người dùng: "đúng như ý kiến", "có thể" và "nhất".
Hệ thống Hypersoft

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 cảm ơn! Khi làm việc với CSS, toString (16) rất quan trọng để bạn nhận được kết quả như FF0000
Tyler Egeto

7
khi làm việc với css (hoặc svg, chấp nhận thông số màu theo kiểu css), bạn có thể bỏ qua toàn bộ vấn đề bằng cách viết color: rgb(r,g,b)trong đó rg và b là số thập phân.
telent

1
Nên là: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

Nếu bạn muốn chuyển đổi một số thành biểu diễn thập lục phân của giá trị màu RGBA, tôi đã thấy đây là sự kết hợp hữu ích nhất của một số mẹo từ đây:

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

8

Nhận xét của AFAIK 57807 là sai và phải là một cái gì đó như: var hex = Number (d) .toString (16); thay vì 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

Và nếu số âm?

Đây là phiên bản của tôi.

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

Tôi đang thực hiện chuyển đổi thành chuỗi hex trong một vòng lặp khá lớn, vì vậy tôi đã thử một số kỹ thuật để tìm ra chuỗi nhanh nhất. Yêu cầu của tôi là có một chuỗi có độ dài cố định và kết quả là mã hóa các giá trị âm đúng (-1 => ff..f).

Đơn giản .toString(16)không làm việc cho tôi vì tôi cần các giá trị âm được mã hóa chính xác. Mã sau đây là mã nhanh nhất tôi đã thử nghiệm cho đến nay trên các giá trị 1-2 byte (lưu ý symbolsxác định số lượng ký hiệu đầu ra bạn muốn nhận, đó là đối với số nguyên 4 byte, nó phải bằng 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;
}

Nó thực hiện nhanh hơn so với .toString(16)các số 1-2 byte và chậm hơn trên các số lớn hơn (khi symbols> = 6), nhưng vẫn vượt trội so với các phương pháp mã hóa giá trị âm đúng cách.


5

Như câu trả lời được chấp nhận, cách dễ nhất để chuyển đổi từ thập phân sang thập lục phân là var hex = dec.toString(16). Tuy nhiên, bạn có thể thích thêm một chuyển đổi chuỗi, vì nó đảm bảo rằng các biểu diễn chuỗi như "12".toString(16)hoạt động chính xác.

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

Để đảo ngược quá trình, bạn cũng có thể sử dụng giải pháp dưới đây, vì nó thậm chí còn ngắn hơn.

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

Nó dường như chậm hơn trong Google Chrome và Firefox, nhưng nhanh hơn đáng kể trong Opera. Xem http://jsperf.com/hex-to-dec .


5

Cách chuyển đổi thập phân thành thập lục phân trong JavaScript

Tôi đã không thể tìm thấy một chuyển đổi thập phân đơn giản / thập phân đơn giản thành thập lục phân không liên quan đến sự lộn xộn của các hàm và mảng ... vì vậy tôi phải tự thực hiện điều này.

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
Ôi ... đây là một cách thực sự khủng khiếp, khủng khiếp để làm điều này, được thực hiện theo phong cách mã hóa thậm chí còn xấu hơn. Thành thật: có gì sai với ngắt dòng và thụt dòng? Biến chữ đơn? Có thật không?
Victor Schröder

1
Sửa lại nó. Đây có phải là cách khủng khiếp? Và phong cách có tốt hơn không ?? Ban đầu tôi nghĩ sẽ dễ hiểu hơn với từng bước "nghĩa đen" được đánh vần như thế bằng các chữ cái ... đôi khi tôi có thể khá ngu ngốc
JonLikeSquirrel

4
Xin lỗi, vâng, vẫn khủng khiếp. Mã của bạn vẫn sử dụng nhiều vòng lặp không hiệu quả và gây ô nhiễm không gian tên toàn cầu, trong số các vấn đề khác. Cách tiếp cận chính nó là quá mức cần thiết cho một nhiệm vụ có thể được thực hiện bằng một cuộc gọi chức năng đơn giản. Nếu bạn muốn cải thiện phong cách mã hóa của mình trong JS, tôi thực sự khuyên bạn nên đọc tài liệu như w3.org/wiki/JavaScript_best_practicesgoogle.github.io/styleguide/javascriptguide.xml . Chỉ cần google về chủ đề.
Victor Schröder

1
Tôi đã thực hiện kiểm tra tốc độ trong Chrome và chức năng quá mức của tôi nhanh hơn khoảng 30% so với .toString (16), trong khi ở Firefox, chức năng của tôi chậm hơn 40% so với .toString (16) ... Chrome chứng minh rằng các vòng lặp quá mức của tôi hiệu quả hơn so với chức năng .toString (16) của trình duyệt, trong khi Firefox chứng minh tại sao nhiều người thích Chrome hơn. Hay là ngược? Một ngày nào đó Chrome thậm chí có thể cập nhật lên .toString (16) nhanh hơn khiến tôi không chính xác trong cả hai trường hợp! Dù bằng cách nào tôi cũng không hoàn toàn sai, và bạn không hoàn toàn đúng. Mặc dù cái tôi của tôi sang một bên, tôi nhận được điểm của bạn ít nhất 30%. ;)
JonLikeSquirrel

2
Bạn không bao giờ phải khai báo một chuỗi các chuỗi chứa mỗi ký tự. Chỉ cần khai báo một chuỗi ký tự. Bạn có thể nhận được một ký tự từ một chuỗi giống như bạn làm với một mảng, bằng cách sử dụng dấu ngoặc vuông.
David Spector

3

Tổng hợp tất cả lên;

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

Tuy nhiên, nếu bạn không cần phải chuyển đổi nó trở lại thành một số nguyên ở cuối (nghĩa là đối với màu sắc), thì chỉ cần đảm bảo rằng các giá trị không âm sẽ đủ.


2

Tôi chưa tìm thấy câu trả lời rõ ràng, không có kiểm tra nếu nó âm hay dương, sử dụng hai phần bù (bao gồm số âm). Vì thế, tôi chỉ ra giải pháp của mình cho một byte:

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

Bạn có thể sử dụng hướng dẫn này cho bất kỳ byte số nào, chỉ bạn thêm FFvào những nơi tương ứng. Ví dụ: hai byte:

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

Nếu bạn muốn truyền một số nguyên mảng thành chuỗi thập lục phân:

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

2

Trong trường hợp bạn đang muốn chuyển đổi thành một đại diện JavaScript hoặc CSS 'đầy đủ', bạn có thể sử dụng một cái gì đó như:

  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

2

Bạn có thể làm một cái gì đó như thế này trong ECMAScript 6 :

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

1

Nếu bạn đang tìm cách chuyển đổi các số nguyên lớn, tức là Số lớn hơn Number.MAX_SAFE_INTEGER - 9007199254740991, thì bạn có thể sử dụng mã sau

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


1

Điều này dựa trên các giải pháp của Prestaul và Tod. Tuy nhiên, đây là một khái quát hóa chiếm kích thước khác nhau của một biến (ví dụ: Phân tích giá trị đã ký từ nhật ký nối tiếp vi điều khiển).

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

Kịch bản thử nghiệm:

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

Kết quả kiểm tra:

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'

Lưu ý: Không quá chắc chắn tại sao nó thất bại trên 32 bitize


-3

Đây là giải pháp của tôi:

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

Câu hỏi cho biết: "Cách chuyển đổi thập phân thành thập lục phân trong JavaScript" . Trong khi, câu hỏi không xác định rằng chuỗi thập lục phân nên bắt đầu với một 0x tiền tố, bất cứ ai viết code nên biết rằng 0x được thêm vào mã thập lục phân để phân biệt mã thập lục phân từ định danh chương trìnhsố khác (1234 có thể là hệ thập lục phân, thập phân, hoặc chẵn bát phân).

Do đó, để trả lời chính xác câu hỏi này, với mục đích viết kịch bản, bạn phải thêm tiền tố 0x.

Hàm Math.abs (N) chuyển đổi các phủ định thành tích cực và như một phần thưởng, nó không giống như ai đó đã điều hành nó thông qua một máy băm gỗ.

Câu trả lời tôi muốn, sẽ có một công cụ xác định độ rộng trường, vì vậy, ví dụ chúng ta có thể hiển thị các giá trị 8/16 / 32/64-bit theo cách bạn sẽ thấy chúng được liệt kê trong ứng dụng chỉnh sửa thập lục phân. Đó là câu trả lời đúng, thực tế.


1
Trong thực tế mã hóa nói chung, bất kỳ chuỗi số alpha nào bắt đầu bằng một chữ cái, KHÔNG PHẢI LÀ SỐ. Ví dụ: ABCDEF012345678 là một định danh hợp lệ trong hầu hết mọi ngôn ngữ mã hóa trên hành tinh.
Hệ thống Hypersoft

1
Ồ, và tiền tố 0x không phải là vấn đề đối với javascript: Number('0xFF') === 255;cho tất cả những người bạn muốn hoạt động ngược lại.
Hệ thống Hypersoft
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.