How to convert decimal to hexadecimal in JavaScript
Asked Answered
W

30

1931

How do you convert decimal values to their hexadecimal equivalent in JavaScript?

Whitsunday answered 11/9, 2008 at 22:26 Comment(2)
Just a warning here that is you are starting from a string representation its very easy to lose precision when you turn it into Number as part of converting it to hex. See danvk.org/wp/2012-01-20/….Charr
This function is exactly what you needGerigerianna
H
3204

Convert a number to a hexadecimal string with:

hexString = yourNumber.toString(16);

And reverse the process with:

yourNumber = parseInt(hexString, 16);
Hub answered 11/9, 2008 at 22:28 Comment(21)
isn't it yourNum = parseInt(yourNum, 10); -- and not 16?Relax
yourNum is a hex string in this case. E.g. (255).toString(16) == 'ff' && parseInt('ff', 16) == 255Hub
Can someone point me to documentation on toString() parameters? This is working for me, but I'd like to format the string a bit. According to MDN, toString() doesn't accept any parameters: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…Kinship
You were looking at Object.toString. You need Number.toString()... developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…Hub
on larger numbers one looses precision apparently. See my questionSeddon
@forste, you will not "loose precision" if you convert a javascript Number (that is a Number object, which in ECMA script is a Double) to hex and back using this technique. The question you linked is specifically referencing numbers too large to fit into a Double (hence the string representation in the question). If you've got a Number then this will work. If you have something too big to be a javascript Number object (a Double) then you'll have to find something else.Hub
@Derek, I have a psychological issue that won't allow me to tolerate unnecessary parentheses... @everyone-else, yourNumber is a variable. If you want to use a numeric literal then you'll have to do something like (45).toString(16), but if you are hard-coding a number then please just write it as a hex string yourself... (45).toString(16) will always equal '2d', so don't waste cpu cycles to figure that out.Hub
@Hub - var a = 16.toString(16) ==> SyntaxError: Unexpected token ILLEGAL You have to put the number in parentheses.Hoahoactzin
@Derek, please reread my previous comment where I clarify 1) that yourNumber is a variable, not a numeric literal, and 2) why you should never need to type (16).toString(16)Hub
@Derek朕會功夫 Shame you removed all your comments. :P Would've liked to see the discussion in full.Labana
@Hub "Don't waste cpu cycles to figure that out" - that's called premature optimization. Unless the JavaScript is running on a 286, I doubt the overhead matters. Furthermore, '45' might be a magic number that the programmer needs to be able to recognize (such as timeout duration in seconds), whereas '2d', well who's going to recognize that?Maddy
@DejayClayton, I don't disagree with you. Clarity/simplicity over premature optimization. However, there are two main cases in my mind. One is that you are dealing with binary/hex data and in those cases writing hex is clearer than writing decimal. (e.g. 'ff' is clearer than 255) The other is that you have numeric data (your example) with a hex encoding and in those cases I think it is clearer to assign a numeric value and not encode until you need a hex string. e.g. (var timeout = 45; ... doSomething(timeout.toString(16));)Hub
If you don't like the parentheses, you can just use an extra dot: 42..toString(16)Windflower
Worth noting this isn't limited to hex, you can also use octal or binary with toString(8) and toString(2) - as well as any other base you should choose!Thermit
@ThomasWatson what kind of sorcery is this ?Filibeg
@CiprianTomoiaga In JavaScript all numbers are floats. So 42 is the same as 42.0. But it's legal to omit the zero and write 42.. So if you write 42.toString(16), the period isn't seen as if you're trying to call a function, but as decimal point. So to actually call a function you have to add an extra period after the decimal pointWindflower
In case some people may want to convert a big integer, they may have a look of here: #18627344Gaucho
And if you don't like the parentheses, nor the extra dot, add a space: 42 .toString(16)Lander
Is there any shortest form to convert hex->dec instead parseInt(x,16) ?Feltner
@gkucmierz, I don't think it gets any shorter than that. Not much different than python (int(x, 16)) or java (Integer.parseInt(x, 16)) or go (strconv.ParseInt(x, 16, 64)) or almost any other language.Hub
@Feltner You can wrap it in a function const parseHex = x => parseInt(x, 16) and then you use it like parseHex('ff') which returns 255.Dominickdominie
P
169

If you need to handle things like bit fields or 32-bit colors, then you need to deal with signed numbers. The JavaScript function toString(16) will return a negative hexadecimal number which is usually not what you want. This function does some crazy addition to make it a positive number.

function decimalToHexString(number)
{
  if (number < 0)
  {
    number = 0xFFFFFFFF + number + 1;
  }

  return number.toString(16).toUpperCase();
}

console.log(decimalToHexString(27));
console.log(decimalToHexString(48.6));
Psf answered 30/3, 2009 at 16:5 Comment(4)
This conversion is normally not needed as JavaScript can represent all 32-bit bit fields as unsigned numbers (See Number.MAX_SAFE_INTEGER). For the same reason the conversion to unsigned can be written as: number = 0x100000000 + number;Weber
A short note on my previous comment: While hex representation should work for numbers up to Number.MAX_SAFE_INTEGER this doesn't hold for bitwise operations (which are often used to create 32-bit colors). The result of bitwise operations is always a signed 32-bit integer. Therefore bitwise results >= 2^31 are negative and 0x100000000 | 0 === 0.Weber
You can use >>> operator to convert number to unsigned representation e.g. ((-3253) >>> 0).toString(16) returns "fffff34b".Haemoid
+1 for a useful addition, but if you're converting numbers to a different notation, all of the numbers are "usually" positive already, or else you want negative results.Smolder
W
110

The code below will convert the decimal value d to hexadecimal. It also allows you to add padding to the hexadecimal result. So 0 will become 00 by default.

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;
}
Whitsunday answered 11/9, 2008 at 22:29 Comment(3)
This won't properly handle negative values. decimalToHex(-6, 4) would return 00-6.Fistulous
It also has problems with floats, but putting in Math.round() fixed that. (+1ed)Rhabdomancy
I am "pulling" numbers from an array ('255,0,55', etc) and the .toString(16) didn't work. All I got were the same numbers! I added the "Number" function to the front, and now it works! Only spent about four hours trying to find the solution!!Lubbi
L
76
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
Laciniate answered 5/11, 2012 at 21:8 Comment(5)
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }Prado
It's not that hard to extend it, you are slicing off the last digits with .slice(-number) there. If you add more zeros to the front it'll work fine.Ingeminate
ES6 const hex = d => Number(d).toString(16).padStart(2, '0') 😁Setzer
@NinhPham voovv, what a brilliant answer :)Govern
"0" or "0o" is octal prefix, for hex string representation it should be "0x" or "0X"Gangland
F
57

For completeness, if you want the two's-complement hexadecimal representation of a negative number, you can use the zero-fill-right shift >>> operator. For instance:

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

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

There is however one limitation: JavaScript bitwise operators treat their operands as a sequence of 32 bits, that is, you get the 32-bits two's complement.

Fisherman answered 14/6, 2013 at 10:59 Comment(3)
this is by far the most valuable answer to this question :)Remark
Digging through all the questions because C# number to hexadecimal was producing different results to Javascript number to hexadecimal. It looks like Javascript has the issue with negative numbers. This answer seems to be the solution to the problem.Clemmie
This was massively helpful, thank you! I was using this for RGB colours, so to get the 24-bit variant, chop of the first two characters (the extra FF) - ((-2)>>>0).toString(16).substring(2)Bessiebessy
M
39

With padding:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
Mose answered 13/7, 2011 at 14:29 Comment(1)
@Lucas It returns the last 4 characters.Dominickdominie
S
25

The accepted answer did not take into account single digit returned hexadecimal codes. This is easily adjusted by:

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

and

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

    return a;
}

I believe the above answers have been posted numerous times by others in one form or another. I wrap these in a toHex() function like so:

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

Note that the numeric regular expression came from 10+ Useful JavaScript Regular Expression Functions to improve your web applications efficiency.

Update: After testing this thing several times I found an error (double quotes in the RegExp), so I fixed that. HOWEVER! After quite a bit of testing and having read the post by almaz - I realized I could not get negative numbers to work.

Further - I did some reading up on this and since all JavaScript numbers are stored as 64 bit words no matter what - I tried modifying the numHex code to get the 64 bit word. But it turns out you can not do that. If you put "3.14159265" AS A NUMBER into a variable - all you will be able to get is the "3", because the fractional portion is only accessible by multiplying the number by ten(IE:10.0) repeatedly. Or to put that another way - the hexadecimal value of 0xF causes the floating point value to be translated into an integer before it is ANDed which removes everything behind the period. Rather than taking the value as a whole (i.e.: 3.14159265) and ANDing the floating point value against the 0xF value.

So the best thing to do, in this case, is to convert the 3.14159265 into a string and then just convert the string. Because of the above, it also makes it easy to convert negative numbers because the minus sign just becomes 0x26 on the front of the value.

So what I did was on determining that the variable contains a number - just convert it to a string and convert the string. This means to everyone that on the server side you will need to unhex the incoming string and then to determine the incoming information is numeric. You can do that easily by just adding a "#" to the front of numbers and "A" to the front of a character string coming back. See the toHex() function.

Have fun!

After another year and a lot of thinking, I decided that the "toHex" function (and I also have a "fromHex" function) really needed to be revamped. The whole question was "How can I do this more efficiently?" I decided that a to/from hexadecimal function should not care if something is a fractional part but at the same time it should ensure that fractional parts are included in the string.

So then the question became, "How do you know you are working with a hexadecimal string?". The answer is simple. Use the standard pre-string information that is already recognized around the world.

In other words - use "0x". So now my toHex function looks to see if that is already there and if it is - it just returns the string that was sent to it. Otherwise, it converts the string, number, whatever. Here is the revised toHex function:

/////////////////////////////////////////////////////////////////////////////
//  toHex().  Convert an ASCII string to hexadecimal.
/////////////////////////////////////////////////////////////////////////////
toHex(s)
{
    var l = "0123456789ABCDEF";
    var o = "";

    if (typeof s != "string") {
        s = s.toString();
    }

    if (s.substr(0,2).toLowerCase() == "0x") {
        return s;
    }

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

This is a very fast function that takes into account single digits, floating point numbers, and even checks to see if the person is sending a hex value over to be hexed again. It only uses four function calls and only two of those are in the loop. To un-hex the values you use:

/////////////////////////////////////////////////////////////////////////////
//  fromHex().  Convert a hex string to ASCII text.
/////////////////////////////////////////////////////////////////////////////
fromHex(s)
{
    var start = 0;
    var o = "";

    if (typeof s != "string") {
        s = s.toString();
    }

    if (s.substr(0,2).toLowerCase() == "0x") {
        start = 2;
    }

    for (var i=start; i<s.length; i+=2) {
        var c = s.substr(i, 2);

        o = o + String.fromCharCode(parseInt(c, 16));
    }

    return o;
}

Like the toHex() function, the fromHex() function first looks for the "0x" and then it translates the incoming information into a string if it isn't already a string. I don't know how it wouldn't be a string - but just in case - I check. The function then goes through, grabbing two characters and translating those in to ASCII characters. If you want it to translate Unicode, you will need to change the loop to going by four(4) characters at a time. But then you also need to ensure that the string is NOT divisible by four. If it is - then it is a standard hexadecimal string. (Remember the string has "0x" on the front of it.)

A simple test script to show that -3.14159265, when converted to a string, is still -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;

?>

Because of how JavaScript works in respect to the toString() function, all of those problems can be eliminated which before were causing problems. Now all strings and numbers can be converted easily. Further, such things as objects will cause an error to be generated by JavaScript itself. I believe this is about as good as it gets. The only improvement left is for W3C to just include a toHex() and fromHex() function in JavaScript.

Update : After reading the comments below, the first IF statement should come after the test to see if "s" is a string.

Speedball answered 6/11, 2014 at 16:21 Comment(5)
I think you've still got work to do here... if( s.substr(0,2) before if (typeof s != "string") probably isn't what you want, for instance. What I had returned wasn't what I expected either (toHex(0x1f635) gives "0x313238353635"). Have not investigated further.Immingle
I believe you are incorrect. Your example is using a hex string which is NOT a string - but a number. Therefore the 1f635 would come out the way it is. If you had of put in "0x1f635" it would have come out differently. (i.e.: the routine would have just returned the hex number you had sent to the routine.) :-)Speedball
The first point was that you can't use substr & toLowerCase on a non-string... so either the typeof needs to come sooner, or, if you expected toHex to throw on a non-string right there, you should remove the typeof check completely. Make sense? That is, if I used the code here without edits, and called toHex(0x1f635), I'd get Uncaught TypeError: s.substr is not a function. If I move the string cast earlier, you're right, the number casts to decimal first, perhaps, and things go sideways. Which of course means you can't do a simple cast here if s is not a string.Immingle
Actually, under XP this works fine. There have been a number of updates to Javascript which are making Javascript be typecast. Which would throw an exception. Under XP it jusr works. At least for me. In a typecast world - putting "if( typeof s == "string" && s.substr(0,2) == "0x"){return s;}" is appropriate. But ox1f635 is still not a string. :-)Speedball
To ruffin - you are right. The conversion to a string should go in front of the IF statement which does a substr. Corrected.Speedball
M
21

Without the loop:

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

Also isn't it better not to use loop tests that have to be evaluated?

For example, instead of:

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

have

for (var i = 0, var j = hex.length; i < j; i++){}
Moncada answered 11/9, 2010 at 3:5 Comment(0)
S
20

Combining some of these good ideas for an RGB-value-to-hexadecimal function (add the # elsewhere for 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);
}
Somato answered 15/11, 2012 at 12:44 Comment(1)
Thanks for this! I ment to drop a comment a long time ago. It was the key for my answer. #5560748Chivalry
E
17

For anyone interested, here's a JSFiddle comparing most of the answers given to this question.

And here's the method I ended up going with:

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

Also, bear in mind that if you're looking to convert from decimal to hex for use in CSS as a color data type, you might instead prefer to extract the RGB values from the decimal and use rgb().

For example (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 + ')')

This sets #some-element's CSS color property to rgb(64, 62, 154).

Evangelist answered 10/11, 2015 at 4:23 Comment(0)
W
16

Constrained/padded to a set number of characters:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
Winn answered 27/1, 2012 at 13:35 Comment(1)
This converts a number to a string hex AND pads leading zeros, this is beautiful!Apnea
A
13
var number = 3200;
var hexString = number.toString(16);

The 16 is the radix and there are 16 values in a hexadecimal number :-)

Amberlyamberoid answered 11/9, 2008 at 22:32 Comment(0)
D
10
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
}
Dwarfism answered 30/5, 2009 at 18:47 Comment(3)
+1 thanks! When working with CSS, the toString(16) is important so you get results like FF0000Virgate
when working with css (or svg, which accepts css-style color specifications) you can sidestep the entire issue by writing color: rgb(r,g,b) where r g and b are decimal numbers.Disapprove
Should be: 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 }Pitching
T
9

If you want to convert a number to a hexadecimal representation of an RGBA color value, I've found this to be the most useful combination of several tips from here:

function toHexString(n) {
    if(n < 0) {
        n = 0xFFFFFFFF + n + 1;
    }
    return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}
Thesda answered 13/6, 2012 at 9:48 Comment(0)
R
8

AFAIK comment 57807 is wrong and should be something like: var hex = Number(d).toString(16); instead of 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;
}
Rinee answered 11/9, 2008 at 22:27 Comment(0)
C
7

As the accepted answer states, the easiest way to convert from decimal to hexadecimal is var hex = dec.toString(16). However, you may prefer to add a string conversion, as it ensures that string representations like "12".toString(16) work correctly.

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

To reverse the process you may also use the solution below, as it is even shorter.

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

It seems to be slower in Google Chrome and Firefox, but is significantly faster in Opera. See http://jsperf.com/hex-to-dec.

Crisper answered 10/6, 2013 at 11:57 Comment(0)
B
6

And if the number is negative?

Here is my version.

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);
}
Blindworm answered 21/10, 2012 at 7:32 Comment(0)
B
6

Converting hex color numbers to hex color strings:

A simple solution with toString and ES6 padStart for converting hex color numbers to hex color strings.

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

For example:

0x000000 will become #000000
0xFFFFFF will become #FFFFFF

Check this example in a fiddle here

Brawny answered 18/2, 2022 at 10:18 Comment(0)
J
5

I'm doing conversion to hex string in a pretty large loop, so I tried several techniques in order to find the fastest one. My requirements were to have a fixed-length string as a result, and encode negative values properly (-1 => ff..f).

Simple .toString(16) didn't work for me since I needed negative values to be properly encoded. The following code is the quickest I've tested so far on 1-2 byte values (note that symbols defines the number of output symbols you want to get, that is for 4-byte integer it should be equal to 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;
}

It performs faster than .toString(16) on 1-2 byte numbers and slower on larger numbers (when symbols >= 6), but still should outperform methods that encode negative values properly.

Juju answered 13/12, 2012 at 17:35 Comment(0)
F
4

You can do something like this in ECMAScript 6:

const toHex = num => (num).toString(16).toUpperCase();
Fluorescence answered 30/1, 2019 at 12:59 Comment(0)
P
3

How to convert decimal to hexadecimal in JavaScript

I wasn't able to find a brutally clean/simple decimal to hexadecimal conversion that didn't involve a mess of functions and arrays ... so I had to make this for myself.

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
Pathological answered 7/2, 2016 at 9:15 Comment(5)
Oh my... this is a really terrible, horrible way of doing this, done in even uglier coding style. Honestly: what is wrong with line breaks and indentation? Single letter variables? Really?Paisley
Revised it. Is this way horrible? And is the style better?? I originally thought it would be easier to understand with every single step "literally" spelled out like that with letters ... sometimes I can be pretty stupidPathological
Sorry, yes, still terrible. Your code still uses lots of inefficient loops and is polluting the global namespace, among other issues. The approach itself is overkill for a task that can be accomplished by a simple function call. If you want to improve your coding style in JS, I strongly recommend that you go read material such as w3.org/wiki/JavaScript_best_practices and google.github.io/styleguide/javascriptguide.xml. Just google about the subject.Paisley
I did a speed test in Chrome and my overkill function is around 30% faster than .toString(16), while in Firefox my function is 40% slower than .toString(16) ... Chrome proves that my excessive loops are MORE efficient than the browsers native .toString(16) function, while Firefox proves why more people prefer Chrome. Or is that backwards?? One day Chrome may even update to a faster .toString(16) making me incorrect in both cases! Either way I'm not completely wrong, and your not entirely right. My ego aside though, I do get your point at least 30% of it. ;)Pathological
You don't ever have to declare an array of strings containing single characters each. Just declare a character string. You can get a character from a string just as you would with an array, by using square brackets.Athwart
T
3

If you are looking for converting Large integers i.e. Numbers greater than Number.MAX_SAFE_INTEGER -- 9007199254740991, then you can use the following code

const hugeNumber = "9007199254740991873839" // Make sure its in String
const hexOfHugeNumber = BigInt(hugeNumber).toString(16);
console.log(hexOfHugeNumber)
Trier answered 17/5, 2019 at 5:49 Comment(0)
E
3

This is based on Prestaul and Tod's solutions. However, this is a generalisation that accounts for varying size of a variable (e.g. Parsing signed value from a microcontroller serial log).

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

Test script:

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

Test results:

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'

Note: Not too sure why it fails above 32 bitsize

Edyth answered 19/8, 2019 at 6:56 Comment(0)
A
2

To sum it all up;

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

However, if you don't need to convert it back to an integer at the end (i.e. for colors), then just making sure the values aren't negative should suffice.

Arneson answered 10/12, 2013 at 0:14 Comment(0)
M
2

I haven't found a clear answer, without checks if it is negative or positive, that uses two's complement (negative numbers included). For that, I show my solution to one byte:

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

You can use this instruction to any number bytes, only you add FF in respective places. For example, to two bytes:

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

If you want cast an array integer to string hexadecimal:

s = "";
for(var i = 0; i < arrayNumber.length; ++i) {
    s += ((0xFF + arrayNumber[i] +1) & 0x0FF).toString(16);
}
Masera answered 5/11, 2017 at 18:21 Comment(0)
W
2

In case you're looking to convert to a 'full' JavaScript or CSS representation, you can use something like:

  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
Whisler answered 13/3, 2018 at 19:34 Comment(0)
F
2
  • rgb(255, 255, 255) // returns FFFFFF

  • rgb(255, 255, 300) // returns FFFFFF

  • rgb(0,0,0) // returns 000000

  • rgb(148, 0, 211) // returns 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();
          }
    
Flameproof answered 23/1, 2021 at 13:8 Comment(0)
B
0

Arbitrary precision

This solution take on input decimal string, and return hex string. A decimal fractions are supported. Algorithm

  • split number to sign (s), integer part (i) and fractional part (f) e.g for -123.75 we have s=true, i=123, f=75
  • integer part to hex:
    • if i='0' stop
    • get modulo: m=i%16 (in arbitrary precision)
    • convert m to hex digit and put to result string
    • for next step calc integer part i=i/16 (in arbitrary precision)
  • fractional part
    • count fractional digits n
    • multiply k=f*16 (in arbitrary precision)
    • split k to right part with n digits and put them to f, and left part with rest of digits and put them to d
    • convert d to hex and add to result.
    • finish when number of result fractional digits is enough

// @param decStr - string with non-negative integer
// @param divisor - positive integer
function dec2HexArbitrary(decStr, fracDigits=0) {   
    // Helper: divide arbitrary precision number by js number
    // @param decStr - string with non-negative integer
    // @param divisor - positive integer
    function 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 integer
    function 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 integer
    function 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) + r 
        m= n/10|0;
      }
      return r;
    }
    
    
    // dec2hex algorithm starts here
    
    let h= '0123456789abcdef';                                         // hex 'alphabet'
    let m= decStr.match(/-?(.*?)\.(.*)?/) || decStr.match(/-?(.*)/);   // separate sign,integer,ractional
    let 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 part
      r=h[arbMod(i,16)]+r; 
      i=arbDivision(i,16);
    }
            
    if(fracDigits) r+=".";
        
    let n = f.length;
    
    for(let j=0; j<fracDigits; j++) {                                  // frac part
      let 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));
Birck answered 9/2, 2021 at 20:8 Comment(0)
H
0

The problem basically how many padding zeros to expect.

If you expect string 01 and 11 from Number 1 and 17. it's better to use Buffer as a bridge, with which number is turn into bytes, and then the hex is just an output format of it. And the bytes organization is well controlled by Buffer functions, like writeUInt32BE, writeInt16LE, etc.

import { Buffer } from 'buffer';

function toHex(n) { // 4byte
  const 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'
Homothallic answered 18/3, 2022 at 6:28 Comment(0)
M
-3

Here's my solution:

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

The question says: "How to convert decimal to hexadecimal in JavaScript". While, the question does not specify that the hexadecimal string should begin with a 0x prefix, anybody who writes code should know that 0x is added to hexadecimal codes to distinguish hexadecimal codes from programmatic identifiers and other numbers (1234 could be hexadecimal, decimal, or even octal).

Therefore, to correctly answer this question, for the purpose of script-writing, you must add the 0x prefix.

The Math.abs(N) function converts negatives to positives, and as a bonus, it doesn't look like somebody ran it through a wood-chipper.

The answer I wanted, would have had a field-width specifier, so we could for example show 8/16/32/64-bit values the way you would see them listed in a hexadecimal editing application. That, is the actual, correct answer.

Meerkat answered 20/11, 2018 at 8:47 Comment(2)
In general coding practice, any alpha-numeric-sequence beginning with a letter, IS NOT A NUMBER. For example: ABCDEF012345678 is a valid identifier in almost every coding language on the planet.Meerkat
Oh, and the 0x prefix is not a problem for javascript: Number('0xFF') === 255; for all you folks out there who want the reverse operation.Meerkat

© 2022 - 2024 — McMap. All rights reserved.