9

This question is more complicated than it first looks - although still conceptually fairly simple.

I am representing big numbers, which are outside of javascript's max range, as strings of hexadecimal digits (this is in accordance with the approach of node-mysql's bigNumberStrings option).

I simply want to know how can I convert a string of hexadecimal digits into a string of decimal digits of the same numerical value? Obviously, there is a complexity in doing this arising from the fact that you cannot do maths with javascript with large numbers.

I have done a significant amount of searching for a standard solution although I haven't found one yet.

Joshua Bambrick
  • 2,669
  • 5
  • 27
  • 35
  • There are a bunch of [BigInteger Libraries for JS](http://www.joseprio.com/blog/2013/04/27/biginteger-libraries-for-js/). – RobG Feb 10 '14 at 02:36
  • Does this answer your question? [How to convert a very large hex number to decimal in javascript](https://stackoverflow.com/questions/12532871/how-to-convert-a-very-large-hex-number-to-decimal-in-javascript) – cdoublev Dec 26 '20 at 13:43

4 Answers4

5

You could use a standard library like bignumber.js

Javascript

var hex = 'ABCDEF1234567890',
    bignumber = new BigNumber(hex, 16);

console.log(bignumber.toString(10));

Output

12379813812177893520 

On jsFiddle

Xotic750
  • 22,914
  • 8
  • 57
  • 79
  • try to convert '08d948645b86ee3f' with this lib and it gives 637620418119134783 and when you try to convert the same with c# you get 637592770119134783 why arent they the same? – Okan SARICA Jun 18 '21 at 13:20
4

The algorithm itself is quite simple, so no need for a special library, it actually does what you would do on paper, so it is not too inefficient.

function hexToDec(s) {
    var i, j, digits = [0], carry;
    for (i = 0; i < s.length; i += 1) {
        carry = parseInt(s.charAt(i), 16);
        for (j = 0; j < digits.length; j += 1) {
            digits[j] = digits[j] * 16 + carry;
            carry = digits[j] / 10 | 0;
            digits[j] %= 10;
        }
        while (carry > 0) {
            digits.push(carry % 10);
            carry = carry / 10 | 0;
        }
    }
    return digits.reverse().join('');
}

How it works: basically reads hex digits and adds them to the intermediate array of dec value computed so far. Every new hex digit means that the array of dec digits is multiplied by 16 and all carry-overs are distributed to higher order digits. The while loop it to add any additional carry-over as new digits in the array. The last line is just converting the array of dec digits to a string.

Update: Of course, you can make the algorithm more efficient by replacing number 10 everywhere by any other power of 10 (100, 1000, 10000, 100000, ...) and it will work the same. The only requirement that the intermediate values do not exceed mantissa precision (52 bits).

jJ'
  • 3,038
  • 32
  • 25
2

let s='7a', hex='0x'+s, dec=+hex;
console.log(s,'->',dec)
Teamur
  • 67
  • 1
  • 4
  • Please read [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer). While this code block may answer the OP's question, this answer would be much more useful if you explain how this code is different from the code in the question, what you've changed, why you've changed it and why that solves the problem without introducing others. – Saeed Zhiany Jun 18 '22 at 03:28
0

The other answers in this thread didn't work for me, but this one did:

function h2d(s) {

    function add(x, y) {
        var c = 0, r = [];
        var x = x.split('').map(Number);
        var y = y.split('').map(Number);
        while(x.length || y.length) {
            var s = (x.pop() || 0) + (y.pop() || 0) + c;
            r.unshift(s < 10 ? s : s - 10); 
            c = s < 10 ? 0 : 1;
        }
        if(c) r.unshift(c);
        return r.join('');
    }

    var dec = '0';
    s.split('').forEach(function(chr) {
        var n = parseInt(chr, 16);
        for(var t = 8; t; t >>= 1) {
            dec = add(dec, dec);
            if(n & t) dec = add(dec, '1');
        }
    });
    return dec;
}
Julian
  • 539
  • 5
  • 7