On parseInt and Converting Hex to RGB
In this tutorial, we deep dive into the parseInt function and attack a common problem  converting hex colours to RGB.
The other day, I was faced with a task that required me to plunge into a little deeper into JavaScript's parseInt()
function, and gain a better grasp of numeral systems and radixes (bases). The problem was simple. I needed to convert hex colours to RGB. Before we jump into anything, let's look at a few definitions for reference:
 parseInt()  The parseInt() function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems) (ref MDN).
 radix  In mathematical numeral systems, the radix or base is the number of unique digits, including zero, used to represent numbers in a positional numeral system (ref Wikipedia).
 hex  or hexadecimal, is a numbering system that uses 16 as the radix, employing the numerals 0 through 9 and representing digits greater than 9 with the letters A through F (ref dictionary.com).
I use the parseInt()
function very often, but never really stopped to examine its inner workings. Mostly, I've used it to do strict comparisons between strings and integers, something in the form of:
return parseInt($el.getAttribute('dataid')) === i;
Knowing my projects, the assumptions have always been clear that those data attributes would return a string like '25'
or '117'
. However, numbering and parsing integers goes a lot deeper than that. Let's look at the problem I mentioned above.
Converting Hexadecimal Strings to Integers
The problem, as it turns out, is actually quite simple once you understand numeral systems and conversions. And if you have experience with both RGB and hex colours in CSS, then you'd have noticed some patterns by now as well:

000000
in hex is0, 0, 0
in RGB 
ffffff
in hex is255, 255, 255
in RGB  Each pair of characters in the hex string represents one number in the RGB string
 In hex, the darkest value is a 0, and lightness increases from 09 then af
 In RGB, the darkest value is a 0, and lightness increases from 0255
These comparisons have always made it easy for me to "see" colours in both hex and RGB. But what's the actual relationship here? It's obvious that:
 a
00
hex pair is a0
on the RGB scale  a
ff
hex pair is a255
on the RGB scale
That's all well and good, but what about everything in between? Well, based on our definition of hexadecimal up above, our hexadecimal numeral system looks like this:
0123456789abcdef
A quick count shows us 16 characters, but we don't actually need to count to know that. The radix for hexadecimal values is 16, which means 16 digits are responsible for its numbering system. To put that into perspective, we as humans are mostly familiar with base 10 digits, where the 10 digits are:
0123456789
We can construct any number imaginable from these 10 digits.
When we talk about parsing an integer, we're talking about reading a string of digits, and returning an integer of the specified radix. The parseInt()
function allows us to specify a radix as the second argument, like this:
parseInt(string, radix);
So a contrived example would be:
var year = '1985';
parseInt(year, 10); // => 1985
In the above example, we're parsing the string 1985
with a radix of 10
, which obviously returns 1985
. Let's look at some hex strings now:
parseInt('0', 16); // => 0
parseInt('00', 16); // => 0
parseInt('1', 16); // => 1
parseInt('2', 16); // => 2
parseInt('f', 16); // => 15
parseInt('0f', 16); // => 15
parseInt('10', 16); // => 16
parseInt('78', 16) // => 120
parseInt('a6', 16) // => 166
parseInt('ff', 16) // => 255
As expected, the returned integer increases as we move from 0 to f. Here are some other observations as well:
 Leading 0s are ignored when parsing (
0f
is the same asf
)  When we reach
0f
, the next in line is10
 this is equivalent from going from9
to10
in base 10 numbers
Since hex number codes are represented by three twoletter strings* representing red, green, and blue values, we can easily convert a hex colour to RGB like this:
var col = 'f30d91';
var r = col.substr(0, 2);
var g = col.substr(2, 2);
var b = col.substr(4);
return {
r: parseInt(r, 16),
g: parseInt(g, 16),
b: parseInt(b, 16)
};
*Sidenote: hex colour codes can also be represented by a 3 letter string, where each letter is assumed to be repeated once. Example, f03 === ff0033
. This is only related to how CSS interpreters parse colour codes, but not how the hexadecimal scale works, as f !== ff
in hexadecimal.
Subtleties and Nuances of parseInt
Before wrapping up, let's take a quick look at some subtleties and nuances of the parseInt()
function, as taken from the MDN:

If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point:
parseInt('02', 2); // => 0 parseInt('101', 2); // => 5 parseInt('102', 2); // => 2 parseInt('10', 2); // => 2

parseInt
truncates numbers to integer values  Leading and trailing spaces are allowed
 If radix is undefined or 0 (or absent), JavaScript assumes the following:
 If the input string begins with "0x" or "0X", radix 16 is assumed
 If the input string begins with "0", radix 8 or 10 is assumed, and the choice is implementation dependent
 If the input string begins with any other value, radix 10 is assumed

If the first character cannot be converted to a number, parseInt returns NaN:
parseInt('2', 2); // => NaN parseInt('hello', 8); // => NaN
 For arithmetic purposes, the NaN value is not a number in any radix
A Final Word of Advice
As a final word of advice, I'd say that from now on, whenever you use the parseInt
function, you should also specify the radix, even though it's optional, and here's why:
 Based on the nuances described above, we can't always hope for consistent behaviour.
 We can't assume that fellow developers will know what radix system we're working with when they look at our code.
Wrap Up
And thatâ€™s a wrap! I hope this little tutorial helped you learn a bit more about numeral systems, radixes, and parsing integers. I certainly did! Thanks for reading, and if you have and questions, comments, or feedback, feel free to leave them below.