如何在javascript中将非常大的十六进制数转换为十进制

问题描述 投票:0回答:7

我正在尝试将非常大的十六进制数转换为十进制数,但没有取得太大成功。 我的问题是使用

decimal = parseInt(hex, 16)
当我尝试转换 14 位以上的十六进制数字时,出现数字错误。

我在 Java 中对此没有问题,但 Javascript 似乎在 14 位十六进制以上并不准确。

我尝试过“BigNumber”,但这给了我同样的错误结果。

我已尽我所能在网络上搜索,找到了可以进行转换的网站,但无法弄清楚如何直接进行转换。

我尝试依次获取每个字符并将其乘以其因子,即 123456789abcdef 15 * Math.pow(16, 0) + 14 * Math.pow(16, 1).... 等等,但我认为(作为一个菜鸟)我的子例程可能没有达到应有的效果,因为我完全得到了一个(我的意思是真的不同!)回答。

如果对你们有帮助,我可以发布我到目前为止所写的内容供你们查看,但我希望有人能为我提供简单的答案。

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

谢谢你。

保罗

javascript hex
7个回答
31
投票

新的简单方法

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

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

var d = bn.toString(10);

BigInt
现在在大多数浏览器(IE 除外)中可用

本答案前面:

如果您需要处理负数,则需要做一些工作:

本质上:

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

25
投票

好吧,让我们试试这个:

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

测试:

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

打印

342789023478234789127089427304981273408912349586345899239

哪个是正确的(请随时验证)。


2
投票

请注意,“0x”+“ff”将被视为 255,因此请将十六进制值转换为字符串并在前面添加“0x”。

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

1
投票

如果您对十六进制字符串使用“0x”表示法,请不要忘记添加

s = s.slice(2)
以删除“0x”前缀。


1
投票

BigInt 构造函数可以采用十六进制字符串作为参数:

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

用途:

Hex2decimal("100");

输出:

256

抄袭了另一个答案,但没有无意义的 0 填充 =P


0
投票

请记住,JavaScript 仅具有单一数字类型(双精度型),并且不提供任何单独的整数类型。因此它可能无法存储您数字的精确表示。

为了获得准确的结果,您需要使用任意精度整数的库,例如BigInt.js。例如代码:

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

正确地将

0x5061756c205768697465
转换为
379587113978081151906917
的预期结果。

如果您想尝试上面列出的代码,

这里是一个jsfiddle。


0
投票

我来这里寻找十六进制的负 BigInt

function bufferToBigInt(buf) {
    const num = BigInt(`0x${buf.toString("hex")}`)
    return buf[0] & 0x80 ? num - (1n << (BigInt(buf.length) << 3n)) : num
    //2's complement:
    //MSB(leftmost bit) is supposed to be negative
    //BigInt parses MSB as positive, the rest of bits are parsed correctly as positive
    //MSB - (MSB<<1) makes it negative
}

如果您不使用 Node.js,这里有一个浏览器解决方案

function hexToBigInt(hex) {
    const num = BigInt(`0x${hex}`)
    //odd length: padded to 0X: positive
    //MSB:0, [0-7]X: positive

    return ((hex.length & 1) || hex[0] < '8') ? num : num - (1n << (BigInt((hex.length + 0b1) & -2) << 2n))
    //align to 4 byte boundary would be:
    // (hex.length + 0b11) & 0b11111111111111111111111111111100
    // (hex.length + 3) & ~3
    // (hex.length + 3) & -4
}
© www.soinside.com 2019 - 2024. All rights reserved.