如何在JavaScript中将十进制值转换为等效的十六进制值?
如果要将数字转换为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值到十六进制的功能(在其他地方为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);
}
我正在一个相当大的循环中进行到十六进制字符串的转换,所以我尝试了几种技巧以找到最快的一种。 我的要求是使用固定长度的字符串,并正确编码负值(-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时),它的性能较慢,但仍应胜过正确编码负值的方法。
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;
}
如公认的答案所述,从十进制转换为十六进制的最简单方法是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 。
为了完整起见 ,如果要用负数的二进制补码十六进制表示形式,可以使用零填充右移>>>
运算符 。 例如:
> (-1).toString(16)
"-1"
> ((-2)>>>0).toString(16)
"fffffffe"
但是,存在一个局限性: JavaScript按位运算符将其操作数视为32位序列 ,也就是说,您获得了32位二进制补码。
总结一下;
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
我相信以上答案已经被其他人以一种或另一种形式发布了无数次。 我将它们包装在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导致将浮点值与AND运算之前转换为整数 ,从而删除了句点之后的所有内容。 而不是将值作为一个整体(即:3.14159265)并将浮点值与0xF值进行“与” 运算 。
因此,在这种情况下,最好的做法是将3.14159265转换为字符串 ,然后仅转换该字符串。 由于上述原因,这也使转换负数变得容易,因为减号仅在值的前面变为0x26。
因此,我所做的就是确定该变量包含一个数字-只需将其转换为字符串并转换为字符串即可。 对每个人来说,这意味着在服务器端,您将需要对输入的字符串进行十六进制解析,然后确定输入的信息是数字。 您只需在数字前面加上“#”,然后在返回的字符串前面加上“ A”,就可以轻松地做到这一点。 请参见toHex()函数。
玩得开心!
又过了一年又经过了很多思考,我认为确实需要对“ toHex”功能(还有一个“ fromHex”功能)进行改进。 整个问题是“我如何才能更有效地做到这一点?” 我认为to / from十六进制函数不应该关心某些东西是否是小数部分,但同时应确保小数部分包含在字符串中。
因此,问题就变成了“您怎么知道您正在使用十六进制字符串?”。 答案很简单。 使用世界各地已经公认的标准预字符串信息。
换句话说-使用“ 0x”。 因此,现在我的toHex函数将查看是否已经存在,并且已经存在-它只是返回发送给它的字符串。 否则,它将转换字符串,数字等。 这是修改后的十六进制功能:/// // toHex()。 将ASCII字符串转换为十六进制。 / // 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>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
与toHex()函数类似,fromHex()函数首先查找“ 0x”,然后将输入的信息转换为字符串(如果还不是字符串的话)。 我不知道它不是字符串-但以防万一-我检查一下。 然后,该函数执行,抓取两个字符并将其转换为ASCII字符。 如果要转换Unicode,则需要将循环更改为一次四(4)个字符。 但是然后,您还需要确保字符串不能被四整除。 如果是-则它是标准的十六进制字符串。 (请记住,该字符串的前面带有“ 0x”。)
一个简单的测试脚本显示-3.14159265转换为字符串时仍为-3.14159265。
Test