简体   繁体   English

Javascript - 十六进制字符串到十进制字符串

[英]Javascript - hexadecimal string to decimal string

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).我将超出 javascript 最大范围的大数字表示为十六进制数字字符串(这与 node-mysql 的bigNumberStrings选项的方法一致)。

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.显然,这样做很复杂,因为您不能使用大量的 javascript 进行数学运算。

I have done a significant amount of searching for a standard solution although I haven't found one yet.尽管我还没有找到一个标准解决方案,但我已经进行了大量搜索。

You could use a standard library like bignumber.js您可以使用像bignumber.js这样的标准库

Javascript Javascript

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

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

Output输出

12379813812177893520 

On jsFiddlejsFiddle 上

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.它是如何工作的:基本上读取十六进制数字并将它们添加到到目前为止计算的 dec 值的中间数组中。 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.每个新的十六进制数字意味着十进制数字的数组乘以 16,并且所有结转都分配给更高阶的数字。 The while loop it to add any additional carry-over as new digits in the array. while 循环它以将任何额外的结转添加为数组中的新数字。 The last line is just converting the array of dec digits to a string.最后一行只是将 dec 数字数组转换为字符串。

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.更新:当然,您可以通过将数字 10 替换为 10 的任何其他幂(100、1000、10000、100000,...)来提高算法的效率,并且它的工作原理相同。 The only requirement that the intermediate values do not exceed mantissa precision (52 bits).中间值不超过尾数精度(52 位)的唯一要求。

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

 let s='7a', hex='0x'+s, dec=+hex; console.log(s,'->',dec)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM