如何在JavaScript中将十进制转换为十六进制

如何将十进制值转换为JavaScript中的十六进制等效值?

1333765 次浏览

将数字转换为十六进制字符串:

hexString = yourNumber.toString(16);

并反转该过程:

yourNumber = parseInt(hexString, 16);

下面的代码将十进制值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;}
var number = 3200;var hexString = number.toString(16);

16是基数,十六进制数中有16个值:-)

如果您需要处理位字段或32位颜色等内容,那么您需要处理有符号的数字。JavaScript函数toString(16)将返回一个负十六进制数,这通常不是您想要的。此函数做了一些疯狂的加法使其成为正数。

function decimalToHexString(number){if (number < 0){number = 0xFFFFFFFF + number + 1;}
return number.toString(16).toUpperCase();}
console.log(decimalToHexString(27));console.log(decimalToHexString(48.6));

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}

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

没有循环:

function decimalToHex(d) {var hex = Number(d).toString(16);hex = "000000".substr(0, 6 - hex.length) + hex;return hex;}
// Or "#000000".substr(0, 7 - hex.length) + hex;// Or whatever// *Thanks to MSDN

另外,不使用必须评估的循环测试不是更好吗?

例如,而不是:

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

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

带填充:

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

限制/填充到一组字符:

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

如果您想将数字转换为RGBA颜色值的十六进制表示,我发现这是这里几个技巧的最有用的组合:

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

如果数字是负数呢?

这是我的版本。

function hexdec (hex_string) {hex_string=((hex_string.charAt(1)!='X' && hex_string.charAt(1)!='x')?hex_string='0X'+hex_string : hex_string);hex_string=(hex_string.charAt(2)<8 ? hex_string =hex_string-0x00000000 : hex_string=hex_string-0xFFFFFFFF-1);return parseInt(hex_string, 10);}
function toHex(d) {return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()}

结合RGB值到十六进制函数的一些好主意(在超文本标记语言/CSS的其他地方添加#):

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

我正在一个相当大的循环中转换为十六进制字符串,所以我尝试了几种技术来找到最快的一种。我的要求是结果有一个固定长度的字符串,并正确编码负值(-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;}

它在1-2字节数上的执行速度比.toString(16)快,在较大的数字上的执行速度较慢(当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);

它在GoogleChrome和Firefox中似乎较慢,但在Opera中明显较快。

为了完整性,如果您想要负数的二补码十六进制表示,您可以使用零填充右移#0运算符。例如:

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

然而,有一个限制:JavaScript按位运算符将其操作数视为32位序列,即您获得32位2的补码。

总结这一切;

function toHex(i, pad) {
if (typeof(pad) === 'undefined' || pad === null) {pad = 2;}
var strToParse = i.toString(16);
while (strToParse.length < pad) {strToParse = "0" + strToParse;}
var finalVal =  parseInt(strToParse, 16);
if ( finalVal < 0 ) {finalVal = 0xFFFFFFFF + finalVal + 1;}
return finalVal;}

但是,如果您不需要在末尾将其转换回整数(即颜色),那么只需确保值不是负数就足够了。

接受的答案没有考虑个位数返回的十六进制代码。这很容易通过以下方式进行调整:

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

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

我相信上面的答案已经被其他人以这样或那样的形式发布了无数次。我将它们包装在一个toHex()函数中,如下所示:

function toHex(s){var re = new RegExp(/^\s*(\+|-)?((\d+(\.\d+)?)|(\.\d+))\s*$/);
if (re.test(s)) {return '#' + strHex( s.toString());}else {return 'A' + strHex(s);}}

请注意,数字正则表达式来自10+有用的JavaScript正则表达式函数,可提高您的Web应用程序效率

更新:在多次测试这个东西之后,我发现了一个错误(RegExp中的双引号),所以我修复了它。然而!经过相当多的测试并阅读了almaz的帖子-我意识到我无法让负数工作。

此外-我做了一些阅读,因为所有JavaScript数字无论如何都存储为64位字-我尝试修改numHex代码以获取64位字。但事实证明你不能这样做。如果你将“3.14159265”作为一个数字放入变量中-你将能够得到的只是“3”,因为小数部分只能通过重复将数字乘以10(IE: 10.0)来访问。或者换句话说-0xF的十六进制值导致浮点数值在被ANDed之前被转换为整数,从而删除了句点后面的所有内容。而不是将值作为一个整体(即:3.14159265)并将浮点数值与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()函数。

如果你感兴趣,这是一个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 formatlet 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的CSScolor属性设置为rgb(64, 62, 154)

如何在JavaScript中将十进制转换为十六进制

我找不到一个非常干净/简单的十进制到十六进制的转换,它不涉及一堆函数和数组……所以我不得不自己做这个。

function DecToHex(decimal) { // Data (decimal)
length = -1;    // Base string lengthstring = '';    // 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'
dodecimal += string[length];while (length--); // Flip string forwards, with the prefixed '0x'
return (decimal); // return (hexadecimal);}
/* Original: */
D = 3678;    // Data (decimal)C = 0xF;    // CheckA = D;        // AccumulateB = -1;        // Base string lengthS = '';        // 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)
doH += S[B];while (B--)
S = B = A = C = D; // Zero out variablesalert(H);    // H: holds hexadecimal equivalent

我没有找到一个明确的答案,没有检查它是负的还是正的,它使用了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);}

如果您希望转换为“完整”的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

以下是我的解决方案:

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

虽然问题没有指定十六进制字符串应该以0x前缀开头,但任何编写代码的人都应该知道0x被添加到十六进制代码中以区分十六进制码程序标识符其他数字(1234可以是十六进制,十进制,甚至八进制)。

因此,要正确回答这个问题,为了编写脚本,您必须添加0x前缀。

Math.abs(N)函数将负值转换为正值,作为奖励,它看起来不像有人通过木屑切割机运行它。

我想要的答案会有一个字段宽度说明符,因此我们可以例如显示8/16/32/64位值,就像您在十六进制编辑应用程序中看到它们列出的方式一样。这就是实际的正确答案。

你可以在ECMAScript 6中这样做:

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

如果您正在寻找转换大整数,即大于Number.MAX_SAFE_INTEGER--9007199254740991的数字,那么您可以使用以下代码

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

这是基于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 =                                0b0decimalToPaddedHexString(-1, 1) =       0x01 =                                0b1decimalToPaddedHexString(-1, 2) =       0x03 =                               0b11decimalToPaddedHexString(-1, 3) =       0x07 =                              0b111decimalToPaddedHexString(-1, 4) =       0x0F =                             0b1111decimalToPaddedHexString(-1, 5) =       0x1F =                            0b11111decimalToPaddedHexString(-1, 6) =       0x3F =                           0b111111decimalToPaddedHexString(-1, 7) =       0x7F =                          0b1111111decimalToPaddedHexString(-1, 8) =       0xFF =                         0b11111111decimalToPaddedHexString(-1, 9) =     0x01FF =                        0b111111111decimalToPaddedHexString(-1,10) =     0x03FF =                       0b1111111111decimalToPaddedHexString(-1,11) =     0x07FF =                      0b11111111111decimalToPaddedHexString(-1,12) =     0x0FFF =                     0b111111111111decimalToPaddedHexString(-1,13) =     0x1FFF =                    0b1111111111111decimalToPaddedHexString(-1,14) =     0x3FFF =                   0b11111111111111decimalToPaddedHexString(-1,15) =     0x7FFF =                  0b111111111111111decimalToPaddedHexString(-1,16) =     0xFFFF =                 0b1111111111111111decimalToPaddedHexString(-1,17) =   0x01FFFF =                0b11111111111111111decimalToPaddedHexString(-1,18) =   0x03FFFF =               0b111111111111111111decimalToPaddedHexString(-1,19) =   0x07FFFF =              0b1111111111111111111decimalToPaddedHexString(-1,20) =   0x0FFFFF =             0b11111111111111111111decimalToPaddedHexString(-1,21) =   0x1FFFFF =            0b111111111111111111111decimalToPaddedHexString(-1,22) =   0x3FFFFF =           0b1111111111111111111111decimalToPaddedHexString(-1,23) =   0x7FFFFF =          0b11111111111111111111111decimalToPaddedHexString(-1,24) =   0xFFFFFF =         0b111111111111111111111111decimalToPaddedHexString(-1,25) = 0x01FFFFFF =        0b1111111111111111111111111decimalToPaddedHexString(-1,26) = 0x03FFFFFF =       0b11111111111111111111111111decimalToPaddedHexString(-1,27) = 0x07FFFFFF =      0b111111111111111111111111111decimalToPaddedHexString(-1,28) = 0x0FFFFFFF =     0b1111111111111111111111111111decimalToPaddedHexString(-1,29) = 0x1FFFFFFF =    0b11111111111111111111111111111decimalToPaddedHexString(-1,30) = 0x3FFFFFFF =   0b111111111111111111111111111111decimalToPaddedHexString(-1,31) = 0x7FFFFFFF =  0b1111111111111111111111111111111decimalToPaddedHexString(-1,32) = 0xFFFFFFFF = 0b11111111111111111111111111111111Thrown: 'number above maximum value'

注意:不太确定为什么32位以上会失败

  • rgb(255,255,255)//返回FFFFFF

  • rgb(255,255,300)//返回FFFFFF

  • rgb(0,0,0)//返回000000

  • rgb(148,0,211)//返回9400D3

     function rgb(...values){return values.reduce((acc, cur) => {let val = cur >= 255 ? 'ff' : cur <= 0 ? '00' : Number(cur).toString(16);return acc + (val.length === 1 ? '0'+val : val);}, '').toUpperCase();}

任意精度

此解决方案接受输入的十进制字符串,并返回十六进制字符串。支持十进制分数。算法

  • 将数字拆分为符号(s)、整数部分(i)和小数部分(f),例如对于-123.75,我们有s=truei=123f=75
  • 十六进制的整数部分:
    • 如果i='0'停止
    • 获取取模:m=i%16(任意精度)
    • m转换为十六进制数字并放入结果字符串
    • 对于下一步计算整数部分i=i/16(任意精度)
  • 小数部分
    • 计数小数位数n
    • 乘以k=f*16(任意精度)
    • kn数字拆分为右部分并将其放入f,将其余数字拆分为左部分并将其放入d
    • d转换为十六进制并添加到结果。
    • 当结果小数位数足够时完成

// @param decStr - string with non-negative integer// @param divisor - positive integerfunction dec2HexArbitrary(decStr, fracDigits=0) {// Helper: divide arbitrary precision number by js number// @param decStr - string with non-negative integer// @param divisor - positive integerfunction arbDivision(decStr, divisor){// algorithm https://www.geeksforgeeks.org/divide-large-number-represented-string/let ans='';let idx = 0;let temp = +decStr[idx];while (temp < divisor) temp = temp * 10 + +decStr[++idx];
while (decStr.length > idx) {ans += (temp / divisor)|0 ;temp = (temp % divisor) * 10 + +decStr[++idx];}
if (ans.length == 0) return "0";
return ans;}
// Helper: calc module of arbitrary precision number// @param decStr - string with non-negative integer// @param mod - positive integerfunction arbMod(decStr, mod) {// algorithm https://www.geeksforgeeks.org/how-to-compute-mod-of-a-big-number/let res = 0;
for (let i = 0; i < decStr.length; i++)res = (res * 10 + +decStr[i]) % mod;
return res;}
// Helper: multiply arbitrary precision integer by js number// @param decStr - string with non-negative integer// @param mult - positive integerfunction arbMultiply(decStr, mult) {let r='';let m=0;for (let i = decStr.length-1; i >=0 ; i--) {let n = m+mult*(+decStr[i]);r= (i ? n%10 : n) + rm= n/10|0;}return r;}    
    
// dec2hex algorithm starts here    
let h= '0123456789abcdef';                                         // hex 'alphabet'let m= decStr.match(/-?(.*?)\.(.*)?/) || decStr.match(/-?(.*)/);   // separate sign,integer,ractionallet i= m[1].replace(/^0+/,'').replace(/^$/,'0');                   // integer part (without sign and leading zeros)let f= (m[2]||'0').replace(/0+$/,'').replace(/^$/,'0');            // fractional part (without last zeros)let s= decStr[0]=='-';                                                                             // sign
let r='';                                                                                                          // result    
if(i=='0') r='0';        
while(i!='0') {                                                    // integer partr=h[arbMod(i,16)]+r;i=arbDivision(i,16);}            
if(fracDigits) r+=".";        
let n = f.length;    
for(let j=0; j<fracDigits; j++) {                                  // frac partlet k= arbMultiply(f,16);f = k.slice(-n);let d= k.slice(0,k.length-n);r+= d.length ? h[+d] : '0';}            
return (s?'-':'')+r;}







// -----------// TESTS// -----------


let tests = [["0",2],["000",2],["123",0],["-123",0],["00.000",2],  
["255.75",5],["-255.75",5],["127.999",32],];
console.log('Input      Standard          Abitrary');tests.forEach(t=> {let nonArb = (+t[0]).toString(16).padEnd(17,' ');let arb = dec2HexArbitrary(t[0],t[1]);console.log(t[0].padEnd(10,' '), nonArb, arb);});

// Long Example (40 digits after dot)let example = "123456789012345678901234567890.09876543210987654321"console.log(`\nLong Example:`);console.log('dec:',example);console.log('hex:     ',dec2HexArbitrary(example,40));

将十六进制颜色数字转换为十六进制颜色字符串:

toString和ES6padStart的简单解决方案,用于将十六进制颜色数字转换为十六进制颜色字符串。

const string = `#${color.toString(16).padStart(6, '0')}`;

例如:

0x000000会变成#000000
0xFFFFFF会变成#FFFFFF

点击此处查看此示例

问题基本上是期望有多少个填充零。

如果你希望字符串0111来自数字1和17。最好使用缓冲区作为桥接,数字被转换为字节,然后十六进制只是它的输出格式。字节组织由Buffer函数很好地控制,如写UInt32BE写权限等。

import { Buffer } from 'buffer';
function toHex(n) { // 4byteconst buff = Buffer.alloc(4);buff.writeInt32BE(n);return buff.toString('hex');}
> toHex(1)'00000001'> toHex(17)'00000011'> toHex(-1)'ffffffff'> toHex(-1212)'fffffb44'> toHex(1212)'000004bc'