9

我想将一个 64 位整数拆分为两个 32 位整数:

var bigInt = 0xffffff;

var highInt = bigInt >> 8 // get the high bits 0xfff
var lowInt = bigInt // cut of the first part (with &)?

console.log(highInt); // 0xfff
console.log(lowInt); // 0xfff

// set them together again
var reBigInt = (highInt << 8) + lowInt;

不幸的是,无论是得到 highInt 还是得到 lowInt 都不起作用......有人能给我答案我需要如何使用按位运算符吗?

问候

4

2 回答 2

6

编辑JavaScript使用 IEEE 双精度格式表示整数,因此无法存储任意 64 位整数而不会损失精度,除非通过自定义大整数库。对潜在裁剪值的按位运算显然没有意义。


一般来说,对于支持 64 位整数的语言:

一个 64 位的模式是0xffffffffffffffff. 要提取高 32 位,您需要移位 32: >> 32。要提取低 32 位,只需将它们与 32 个:& 0xffffffff.

你的原则是正确的——你关于移位或屏蔽多少位的算术是错误的。

于 2013-02-06T14:48:52.957 回答
5

在 JavaScript 中,所有数字都使用 53 位表示。JavaScript 内部使用浮点表示来存储所有数字,这意味着整数存储为浮点数(尾数有 53 位)

所以用 53 位我们可以表示最大值 2^53 = 9007199254740992。

但是,即使从 53 位数字中,您也不能使用右移和 AND 二进制运算来提取低 32 位和高 21 位。

原因是当我们对任何数字应用二元运算符时 - Javascript 首先将该数字转换为 32 位有符号数,应用二元运算并返回结果。这意味着任何高于 32 的位都将被丢弃。

我使用以下方法从正数 <= 2^53 中提取较高(21 位)和较低(32 位)部分。

var bigNumber = Math.pow(2, 53); // 9007199254740992
var bigNumberAsBinaryStr = bigNumber.toString(2); // '100000000000000000000000000000000000000000000000000000'
// Convert the above binary str to 64 bit (actually 52 bit will work) by padding zeros in the left
var bigNumberAsBinaryStr2 = ''; 
for (var i = 0; i < 64 - bigNumberAsBinaryStr.length; i++) {
    bigNumberAsBinaryStr2 += '0'; 
}; 

bigNumberAsBinaryStr2 += bigNumberAsBinaryStr;

var lowInt = parseInt(bigNumberAsBinaryStr2.substring(0, 32), 2);
var highInt = parseInt(bigNumberAsBinaryStr2.substring(32), 2);

只是为了确认上述逻辑是正确的,让我们尝试从两部分构建 bigNumber

Assert((lowInt * Math.pow(2, 32) + highInt) === bigNumber);
于 2015-03-03T05:11:26.923 回答