在Javascript中将BigInteger转换为Int64

Tom Wu的优秀大整数库JSBN缺少longValue函数,所以我必须自己编写.下面是我的代码,但它无法产生正确的结果.

var Cast_Int64 = function (v)
{
  var bytes = v.toByteArray();
  var value =
  (
    (new BigInteger(bytes[0]).and(new BigInteger(255))).shiftLeft(new BigInteger(56))
  )
    .or(
      (new BigInteger(bytes[1]).and(new BigInteger(255))).shiftLeft(new BigInteger(48))
  )
    .or(
      (new BigInteger(bytes[2]).and(new BigInteger(255))).shiftLeft(new BigInteger(40))
  )
    .or(
      (new BigInteger(bytes[3]).and(new BigInteger(255))).shiftLeft(new BigInteger(32))
  )
    .or(
      (new BigInteger(bytes[4]).and(new BigInteger(255))).shiftLeft(new BigInteger(24))
  )
    .or(
      (new BigInteger(bytes[5]).and(new BigInteger(255))).shiftLeft(new BigInteger(16))
  )
    .or(
      (new BigInteger(bytes[6]).and(new BigInteger(255))).shiftLeft(new BigInteger(8))
  )
    .or(new BigInteger(bytes[7]).and(new BigInteger(255)));
  return value;
};

我有一个整数字符串数组,我尝试强制转换为Int64,但它没有提供正确的答案.

整数字符串数组是:

var arr = [
"90655",
"123423",
"1",
"9223372032559808512",
"18446744071562067967",
"4294967295",
"18446744071562067968",
"0",
"346457745533644",
"18446744073623153357"
];

正确答案(使用(Int64)在C#测试库中)是:

90655
123423
1
9223372032559808512
-2147483649
4294967295
-2147483648
0
346457745533644
-86398259

我的错误答案是:

99676226616033280
135705023634997248
72057594037927936
9223372032559808512
72057594029539327
72057594021150720
72057594029539328
0
88693182856612864
72057594037590442

我有jsbin,你可以在那里测试功能.

编辑:如果我用这个替换Cast_Int64:

var Cast_Int64 = function (v)
{
  return v;
}

然后一切顺利,但所有应该是负面的数字(在C#测试基础中)都是错误的:

90655
123423
1
9223372032559808512
18446744071562067967
4294967295
18446744071562067968
0
346457745533644
18446744073623153357

有效的代码(根据接受的答案改编):

var Cast_Int64 = function (v)
{
  if (v.compareTo(new BigInteger(2).pow(new BigInteger(63))) > 0)
  v = v.subtract(new BigInteger(2).pow(new BigInteger(64)));
  return v;
}

或更短(并且更快):

var Cast_Int64 = function (v)
{
  if (v.compareTo(new BigInteger("9223372036854775808",10)) > 0)
  v = v.subtract(new BigInteger("18446744073709551616",10));
  return v;
}

我把替换的代码放在jsbin.BTW,已经有Cast_UInt64,Cast_Int32和Cast_UInt32函数.

解决方法:

整数算术可以被认为是modular arithmetic(模2 ^ p,其中p是位数).因此负值可以表示为超过2 ^(p-1)的值,即-x = 2 ^ p-x.例如,考虑x = 1:-1 = 2 ^ p – 1.你可以向两边加1,然后取模2 ^ p,你的两边都得0.

因此,为了获得正确的结果,只需从每个大于2 ^ 63的值中减去2 ^ 64(在您的情况下为p = 64):

18446744073623153357 - 2^64 = -86398259
18446744071562067968 - 2^64 = -2147483648

顺便说一句:从这里你可以推断有符号和无符号整数之间的连接.

上一篇:mybatis批量插入


下一篇:建外表实例