How do you convert decimal values to their hexadecimal equivalent in JavaScript?
How do you convert decimal values to their hexadecimal equivalent in JavaScript?
Convert a number to a hexadecimal string with:
hexString = yourNumber.toString(16);
And reverse the process with:
yourNumber = parseInt(hexString, 16);
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));
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;
}
var number = 3200;
var hexString = number.toString(16);
The 16 is the radix and there are 16 values in a hexadecimal number :-)
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
}
You can do something like this in ECMAScript 6:
const toHex = num => (num).toString(16).toUpperCase();
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)
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);
}
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
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();
}
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
This solution take on input decimal string, and return hex string. A decimal fractions are supported. Algorithm
s), integer part (i) and fractional part (f) e.g for -123.75 we have s=true, i=123, f=75i='0' stopm=i%16 (in arbitrary precision)m to hex digit and put to result stringi=i/16 (in arbitrary precision)nk=f*16 (in arbitrary precision)k to right part with n digits and put them to f, and left part with rest of digits and put them to dd to hex and add to result.// @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));
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'
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.