javascript - 在 Javascript 中将 BigInteger 转换为 Int64

标签 javascript casting integer biginteger bigint

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中.顺便说一句,已经有 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^ 的每个值中减去 2^64(在您的情况下为 p=64) 63:

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

顺便说一句:从这里你可以推断出有符号和无符号整数之间的联系。

关于javascript - 在 Javascript 中将 BigInteger 转换为 Int64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20123869/

相关文章:

C# 将对象列表中的对象转换为类型返回左手签名必须是变量错误

c - 为什么有人会在 C 中使用这种类型的转换? float 的引用被强制转换为 int 指针,然后取消引用

c# - 转换与解析

java - Integer.toBinaryString 方法的有符号等效项?

javascript - 样式化 javascript 函数 *显示/隐藏* CSS/HTML/JS

javascript - 按组和标题对数组进行排序

javascript - 定义中尖括号中类名的用途是什么?

javascript - vue.js 入门不起作用

c++ - 如何从 char* 中获取二维 int 数组?

python - 上下循环数字而不在python中使用递归