I have some code which takes strings representing hexadecimal numbers - hex colors, actually - and adds them. For example, adding aaaaaa
and 010101
gives the output ababab
.
However, my method seems unnecessarily long and complicated:
var hexValue = "aaaaaa"; hexValue = "0x" + hexValue; hexValue = parseInt(hexValue, 16); hexValue = hexValue + 0x010101; hexValue = hexValue.toString(16); document.write(hexValue); // outputs 'ababab'
The hex value is still a string after concatenating 0x
, so then I have to change it to a number, then I can add, and then I have to change it back into hex format! There are even more steps if the number I'm adding to it is a hexadecimal string to begin with, or if you take into consideration that I am removing the #
from the hex color before all this starts.
Surely there's a simpler way to do such simple hexadecimal calculations! And just to be clear, I don't mean just putting it all on one line like (parseInt("0x"+"aaaaaa",16)+0x010101).toString(16)
or using shorthand - I mean actually doing less operations.
Is there some way to get javascript to stop using decimal for all of its mathematical operations and use hex instead? Or is there some other method of making JS work with hex more easily?
Uses of Hexadecimal Numbers in JavaScriptJavaScript supports the use of hexadecimal notation in place of any integer, but not decimals. As an example, the number 2514 in hex is 0x9D2, but there is no language-supported way of representing 25.14 as a hex number.
HEX() function in MySQL. HEX() : This function in MySQL is used to return an equivalent hexadecimal string value of a string or numeric Input. If the input is a string then each byte of each character in the string is converted to two hexadecimal digits.
For example, the value 97, in hex might be 61. This is a two digit number, containing character "6" followed by "1". Encoded as ASCII that would be two bytes: the value 54 followed by the value 49 (decimal).
No, there is no way to tell the JavaScript language to use hex integer format instead of decimal by default. Your code is about as concise as it gets but note that you do not need to prepend the "0x" base indicator when you use "parseInt" with a base.
Here is how I would approach your problem:
function addHexColor(c1, c2) { var hexStr = (parseInt(c1, 16) + parseInt(c2, 16)).toString(16); while (hexStr.length < 6) { hexStr = '0' + hexStr; } // Zero pad. return hexStr; } addHexColor('aaaaaa', '010101'); // => 'ababab' addHexColor('010101', '010101'); // => '020202'
As mentioned by a commenter, the above solution is chock full of problems, so below is a function that does proper input validation and adds color channels separately while checking for overflow.
function addHexColor2(c1, c2) { const octetsRegex = /^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i const m1 = c1.match(octetsRegex) const m2 = c2.match(octetsRegex) if (!m1 || !m2) { throw new Error(`invalid hex color triplet(s): ${c1} / ${c2}`) } return [1, 2, 3].map(i => { const sum = parseInt(m1[i], 16) + parseInt(m2[i], 16) if (sum > 0xff) { throw new Error(`octet ${i} overflow: ${m1[i]}+${m2[i]}=${sum.toString(16)}`) } return sum.toString(16).padStart(2, '0') }).join('') } addHexColor2('aaaaaa', 'bogus!') // => Error: invalid hex color triplet(s): aaaaaa / bogus! addHexColor2('aaaaaa', '606060') // => Error: octet 1 overflow: aa+60=10a
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With