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


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


1186
2017-09-11 22:26


起源


这里只是一个警告,就是你从一个字符串表示开始,当你将它转换为Number作为转换为十六进制的一部分时,它很容易丢失精度。看到 danvk.org/wp/2012-01-20/...。 - studgeek


答案:


使用以下代码将数字转换为十六进制字符串:

hexString = yourNumber.toString(16);

并通过以下方式扭转过程:

yourNumber = parseInt(hexString, 16);

1997
2017-09-11 22:28



在这种情况下,yourNum是十六进制字符串。例如。 (255).toString(16)=='ff'&& parseInt('ff',16)== 255 - Prestaul
@forste,如果你将javascript Number(这是一个Number对象,在ECMA脚本中是一个Double)转换为十六进制并使用这种技术返回,你将不会“松散精度”。您链接的问题是专门引用太大而不适合Double的数字(因此问题中的字符串表示)。如果你有一个号码,那么这将有效。如果你有一个太大的东西,不能成为一个javascript数字对象(双人),那么你将不得不找到别的东西。 - Prestaul
@Derek,我有一个心理问题,不允许我容忍不必要的括号...... @ everyone-else, yourNumber 是一个变量。如果你想使用数字文字,那么你将不得不做类似的事情 (45).toString(16),但如果您对数字进行硬编码,请自行将其写为十六进制字符串... (45).toString(16) 永远相等 '2d'所以不要浪费cpu周期来解决这个问题。 - Prestaul
@Prestaul“不要浪费cpu周期来解决这个问题” - 这就是所谓的过早优化。除非JavaScript在286上运行,否则我怀疑开销很重要。此外,'45'可能是程序员需要能够识别的神奇数字(例如超时持续时间,以秒为单位),而'2d',谁会认识到? - Dejay Clayton
如果您不喜欢括号,可以使用额外的点: 42..toString(16) - Thomas Watson


如果需要处理位字段或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));


119
2018-03-30 16:05



是两个补充? - Julian
通常不需要此转换,因为JavaScript可以将所有32位位字段表示为无符号数(请参见Number.MAX_SAFE_INTEGER)。出于同样的原因,转换为unsigned可以写成: number = 0x100000000 + number; - Johannes Matokic
关于我之前评论的简短说明:虽然十六进制表示应适用于Number.MAX_SAFE_INTEGER之前的数字,但这不适用于按位运算(通常用于创建32位颜色)。按位运算的结果始终是带符号的32位整数。因此,按位结果> = 2 ^ 31为负且0x100000000 | 0 === 0。 - Johannes Matokic
您可以使用 >>> 运算符将数字转换为无符号表示,例如 ((-3253) >>> 0).toString(16) 回报 "fffff34b"。 - csharpfolk


下面的代码将十进制值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;
}

68
2017-09-11 22:29



这将无法正确处理负值。 decimalToHex(-6,4)将返回00-6。 - JonMR
它也有浮动问题,但放入Math.round()修复了这个问题。 (+ 1ED) - Michael


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

45
2017-11-05 21:08



这或类似的东西应该是公认的答案。在99%的情况下,您不需要可变长度的十六进制字符串! - user239558
这绝对应该 不 是接受的答案。这是一个非常难以阅读的令人讨厌的单行内容。造成大量不必要的心理开销。它试图确保不变长度的十六进制字符串是毫无意义的hacky,只有当你的数字适合单个字节时才有效(IMO很少见)。 - JMTyler
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); } - Lori
扩展它并不难,你在那里用.slice(-number)切掉最后的数字。如果你在前面添加更多的零,它将正常工作。 - Tatarize
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')  - Ninh Pham


填充:

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

31
2017-07-13 14:29



究竟是怎么做的 .substr(-4) 在这里工作? - Lucas
@Lucas它返回最后4个字符。 - Gabriel


完成后,如果你想要的话 二进制补码 十六进制表示负数,可以使用 零填充 - 右移 >>> 操作者。例如:

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

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

但是有一个限制: javascript位运算符将其操作数视为32位序列也就是说,你得到32位的二进制补码。


25
2018-06-14 10:59



这是迄今为止这个问题最有价值的答案:) - albertjan


没有循环:

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++){}

16
2017-09-11 03:05





将一些好的想法结合起来用于rgb到hex函数(在其他地方为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);
}

13
2017-11-15 12:44



谢谢你!我很久以前就发表评论了。这是我答案的关键。 stackoverflow.com/questions/5560248/... - Pimp Trizkit
这是一个很好的帮助方法,感谢分享 - francisco.preller


接受的答案没有考虑单个数字返回的十六进制代码。这很容易调整:

   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”AS A NUMBER放入变量中 - 您将能够得到的只是“3”,因为小数部分只能通过重复乘以10(IE:10.0)来访问。或者换句话说 - HEX值为0xf会导致FLOATING POINT值在AND运算之前被转换为INTEGER,从而删除该时段背后的所有内容。而不是将值作为一个整体(即:3.14159265)并将FLOATING POINT值与0xf值进行AND运算。因此,在这种情况下,最好的做法是将3.14159265转换为STRING,然后转换字符串。由于上述原因,它也可以很容易地转换负数,因为减号只会在值的前面变为0x26。所以我做的是确定变量包含一个数字 - 只需将其转换为字符串并转换字符串。这对每个人来说意味着在服务器端你需要取消传入的字符串,然后确定传入的信息是数字。只需在数字前面添加“#”,然后在返回的字符串前面添加“A”即可轻松完成。请参阅toHex()函数。

玩的开心!

经过一年多的思考,我认为“toHex”功能(我也有“fromHex”功能)确实需要进行改造。整个问题是“我怎样才能更有效地做到这一点?”我决定一个to / from hex函数不应该关心某个东西是否是一个小数部分,但同时它应该确保小数部分包含在字符串中。那么问题就变成了,“你怎么知道你正在使用十六进制字符串?”。答案很简单。使用世界各地已经识别的标准预字符串信息。换句话说 - 使用“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) == "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()函数。


11
2017-11-06 16:21



我想你还有工作要做...... if( s.substr(0,2) 之前 if (typeof s != "string") 例如,可能不是你想要的。我回来的不是我所期望的(toHex(0x1f635) 给 "0x313238353635")。没有进一步调查。 - ruffin
我相信你是不对的。您的示例使用的是十六进制字符串,它不是字符串 - 而是一个数字。因此1f635会以它的方式出现。如果您输入“0x1f635”,它会以不同的方式出现。 (即:例程将刚刚返回您发送到例程的十六进制数。):-) - Mark Manning
第一点是你不能使用 substr & toLowerCase 在一个非字符串...所以要么 typeof 需要更快,或者,如果你期望 toHex 要在那里抛出一个非字符串,你应该删除 typeof 完全检查。合理?也就是说,如果我在这里使用代码而没有编辑,并调用 toHex(0x1f635),我明白了 Uncaught TypeError: s.substr is not a function。如果我先前移动字符串,你是对的,这个数字可能首先被转换为十进制,并且事情是横向的。这当然意味着你不能在这里做一个简单的演员 s 不是一个字符串。 - ruffin
实际上,在XP下这很好用。 Javascript已经有很多更新,它们使得Javascript被强制转换。哪会引发异常。在XP下它jusr工作。至少对于我来说。在类型转换世界中 - 将“if(typeof s ==”string“&& s.substr(0,2)==”0x“){return s;}”放在适当的位置。但ox1f635仍然不是一个字符串。 :-) - Mark Manning