简体   繁体   中英

How to convert a very large hex number to decimal in javascript

I am trying without much success to convert a very large hex number to decimal. My problem is that using deciaml = parseInt(hex, 16) gives me errors in the number when I try to convert a hex number above 14 digits.

I have no problem with this in Java, but Javascript does not seem to be accurate above 14 digits of hex.

I have tried "BigNumber" but tis gives me the same erroneous result.

I have trawled the web to the best of my ability and found web sites that will do the conversion but cannot figure out how to do the conversion longhand.

I have tried getting each character in turn and multiplying it by its factor ie 123456789abcdef 15 * Math.pow(16, 0) + 14 * Math.pow(16, 1).... etc but I think (being a noob) that my subroutines may not hev been all they should be because I got a completely (and I mean really different.) answer.

If it helps you guys I can post what I have written so far for you to look at but I am hoping someone has simple answer for me.

   <script>
   function Hex2decimal(hex){

   var stringLength = hex.length;
   var characterPosition = stringLength;
   var character;

   var hexChars = new Array();
   hexChars[0] = "0";
   hexChars[1] = "1";
   hexChars[2] = "2";
   hexChars[3] = "3";
   hexChars[4] = "4";
   hexChars[5] = "5";
   hexChars[6] = "6";
   hexChars[7] = "7";
   hexChars[8] = "8";
   hexChars[9] = "9";
   hexChars[10] = "a";
   hexChars[11] = "b";
   hexChars[12] = "c";
   hexChars[13] = "d";
   hexChars[14] = "e";
   hexChars[15] = "f";

   var index = 0;
   var hexChar;
   var result;

   //   document.writeln(hex);

while (characterPosition >= 0)
{
   //   document.writeln(characterPosition);
character = hex.charAt(characterPosition);

    while (index < hexChars.length)
    {
   //       document.writeln(index);
    document.writeln("String Character = " + character);
    hexChar = hexChars[index];
    document.writeln("Hex Character = " + hexChar);

        if (hexChar == character)
        {
        result = hexChar;
        document.writeln(result);
        }

    index++
    }

   //   document.write(character);
characterPosition--;
}

return result;
   }
   </script>

Thank you.

Paul

Ok, let's try this:

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

Test:

t = 'dfae267ab6e87c62b10b476e0d70b06f8378802d21f34e7'
console.log(h2d(t)) 

prints

342789023478234789127089427304981273408912349586345899239

which is correct (feel free to verify).

Notice that "0x" + "ff" will be considered as 255, so convert your hex value to a string and add "0x" ahead.

function Hex2decimal(hex)
{
    return ("0x" + hex) / 1;
} 

如果您对Hex字符串使用'0x'表示法,请不要忘记添加s = s.slice(2)以删除'0x'前缀。

Keep in mind that JavaScript only has a single numeric type (double), and does not provide any separate integer types. So it may not be possible for it to store exact representations of your numbers.

In order to get exact results you need to use a library for arbitrary-precision integers, such as BigInt.js . For example, the code:

var x = str2bigInt("5061756c205768697465",16,1,1);
var s = bigInt2str(x, 10);
$('#output').text(s);

Correctly converts 0x5061756c205768697465 to the expected result of 379587113978081151906917 .

Here is a jsfiddle if you would like to experiment with the code listed above.

The New 'n' Easy Way

var hex = "7FDDDDDDDDDDDDDDDDDDDDDD";
if (hex.length % 2) { hex = '0' + hex; }

var bn = BigInt('0x' + hex);

var d = bn.toString(10);

BigInt s are now available in both node.js and Chrome. Firefox shouldn't be far behind.

If you need to deal with negative numbers, that requires a bit of work:

Essentially:

function hexToBn(hex) {
  if (hex.length % 2) {
    hex = '0' + hex;
  }

  var highbyte = parseInt(hex.slice(0, 2), 16)
  var bn = BigInt('0x' + hex);

  if (0x80 & highbyte) {
    // You'd think `bn = ~bn;` would work... but it doesn't

    // manually perform two's compliment (flip bits, add one)
    // (because JS binary operators are incorrect for negatives)
    bn = BigInt('0b' + bn.toString(2).split('').map(function (i) {
      return '0' === i ? 1 : 0
    }).join('')) + BigInt(1);
    bn = -bn;
  }

  return bn;
}

The BigInt constructor can take a hex string as argument:

/** @param hex = "a83b01cd..." */
function Hex2decimal(hex) {
    return BigInt("0x" + hex).toString(10);
}

Usage:

Hex2decimal("100");

Output:

256

A rip-off from the other answer , but without the meaningless 0 padding =P

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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