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

如何在javascript中将非常大的十六进制数转换为十进制数,javascript,hex,Javascript,Hex,我试图将一个非常大的十六进制数转换成十进制数,但没有成功。 我的问题是使用deciaml=parseInt(十六进制,16) 当我试图转换超过14位的十六进制数时,给出了数字中的错误 在Java中,我对此没有问题,但Javascript在十六进制的14位以上似乎并不准确 我试过“BigNumber”,但它给了我同样的错误结果 我已经尽我最大的能力在网上搜索,找到了可以进行转换的网站,但无法直接找出如何进行转换 我试着依次获得每个字符,并将其乘以其因子,即123456789abcdef 15*Ma

我试图将一个非常大的十六进制数转换成十进制数,但没有成功。 我的问题是使用deciaml=parseInt(十六进制,16) 当我试图转换超过14位的十六进制数时,给出了数字中的错误

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

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

我已经尽我最大的能力在网上搜索,找到了可以进行转换的网站,但无法直接找出如何进行转换

我试着依次获得每个字符,并将其乘以其因子,即123456789abcdef 15*Math.pow(16,0)+14*Math.pow(16,1)。。。。等等,但我认为(作为一个noob),我的子程序可能并不是它们应该有的,因为我得到了一个完全不同的答案

如果这对你们有帮助的话,我可以把我写的东西发布给你们看,但我希望有人能给我一个简单的答案

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

函数Hex2decimal(hex){
var stringLength=十六进制长度;
var characterPosition=字符串长度;
var特征;
var hexChars=新数组();
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指数=0;
var hexChar;
var结果;
//书面文件(十六进制);
while(characterPosition>=0)
{
//文件写入(字符位置);
字符=十六进制字符(characterPosition);
while(索引<六字符长度)
{
//文件记录(索引);
document.writeln(“String Character=“+Character”);
hexChar=hexChars[索引];
document.writeln(“十六进制字符=”+hexChar);
if(hexChar==字符)
{
结果=hexChar;
书面文件(结果);
}
索引++
}
//文件。书写(字符);
字符位置--;
}
返回结果;
}
多谢各位


Paul

请记住,JavaScript只有一个数字类型(double),不提供任何单独的整数类型。因此,它可能无法存储您的数字的精确表示形式

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

var x = str2bigInt("5061756c205768697465",16,1,1);
var s = bigInt2str(x, 10);
$('#output').text(s);
0x5061756c205768697465
正确转换为
379587113978081151906917
的预期结果

如果您想使用上面列出的代码进行实验,那么它就是一个JSFIDLE。

好的,让我们试试这个:

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;
}
印刷品

342789023478234789127089427304981273408912349586345899239
这是正确的(请随意验证)。

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


如果对十六进制字符串使用“0x”表示法,请不要忘记添加
s=s.slice(2)
以删除“0x”前缀

新的简易方法
BigInt
s现在在node.js和Chrome中都可用。Firefox应该不会落后太多

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

基本上:

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

定义一个将数字0-15映射到自身的数组的目的是什么?当我看到“decimal”时,我本能地认为这是一个关于小数的问题,幸好我读得更深入,看看代码数组条目10、11、12、13、14和15应该是a、b、c、d、e,f.我把代码写得有点太快了,因为我想让你们看看我在做什么。如果你们能提供一些测试用例,测试那些
parseInt
没有正确转换的数字,那会很有帮助。好的,我需要转换的是:5061756c205768697465到十进制,应该是379587113978081906917。我得到的parseInt是3.795871139780814e+23。即使我重新设置了数字的格式,这样就不科学了,第16位以后的数字也是不正确的。我已经做了更多的检查,在子程序中我的变量“characther”上看不到一个。把它变成一个全局变量并没有帮助,所以我现在只是把自己挖得更深一些。这就产生了一个错误:对象不支持属性或方法“forEach”。您可能正在使用一个非常旧的浏览器,它不支持这个函数。请参阅以了解如何模拟它。我正在使用frontpage 2003和ie9。这可能是frontpage的一个限制?@PAULWHITE:不知道,但我在没有使用
forEach
的情况下重写了答案。这个版本给了我一个不同的错误:对象不支持属性或方法“map”,实际上需要零填充吗?浏览器控制台似乎会产生奇数刻度数字的预期结果:
BigInt('0x102')==258n
function Hex2decimal(hex)
{
    return ("0x" + hex) / 1;
} 
var hex = "7FDDDDDDDDDDDDDDDDDDDDDD";
if (hex.length % 2) { hex = '0' + hex; }

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

var d = bn.toString(10);
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;
}