移动 JavaScript 中的整数进行存储?

Shifting an integer in JavaScript for storage?

我 运行 遇到了一个看起来有点奇怪的问题,想知道是否有人可以提供帮助。

我正在使用 JavaScript 通过 node.js 存储一些整数,并且想使用从 Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER 的整个整数范围,只是调用负零一个零。

w3schools 看来只允许 52 位(前 52 位),忽略符号,检索 Number.MAX_SAFE_INTEGER 但它显然等于 (2 ^ 53) - 1

另一方面,ECMA spec 表示有 (2 ^ 53) - 2 个值(似乎使用 -0 作为 NaN

我正在尝试将整数打包到尽可能小的位空间中,1 位 (1) 符号,1 位 (2) 表示空值,其余位表示连续更大的数字。只需添加更多行直到最后一行:

// sign is 0 for positive, 1 for negative and 2 for null
byte[0] = ((temp << 2) & 255) + sign;
byte[1] = (temp >> 6) & 255;
byte[2] = (temp >> 14) & 255;
byte[3] = (temp >> 22) & 255;
byte[4] = (temp >> 30) & 255;
byte[5] = (temp >> 38) & 255;
byte[6] = (temp >> 46) & 255; // produces a negative value prior to applying byte mask

Here's a fiddle 加上一些相关代码以防有帮助。

IEEE 浮点格式在尾数上有一个隐含的前导 1 位,但它实际上并不存在。换句话说,所有有效值都有前导 1 位,因此实际上没有必要显式存储它。

您可以查看 this jsfiddle I did the other day 以了解值的表示方式。整数表示为二进制小数乘以 2 的大于 1 的幂,当然整数 1 除外,它的尾数全为零,因为前导隐含 1位。 (实际上2的每一次幂都是尾数中的all-zeros。)

edit — 作为参考,我知道直接获取 floating-point 值中位的最 sure-fire 方法是使用类型化数组:

var f64 = new Float64Array(1);
var u8 = new Uint8Array(f64.buffer);

这为您提供了一个 one-element 64 位数组和一个 8 元素无符号 8 位 int 数组。在 f64 数组中放入一个数字:

f64[0] = Math.sin(x); // or whatever

然后 u8 数组为您提供该值的 8 个字节,最高有效字节(符号位和指数所在的位置)位于 u8[7]。低于 10 的 IE 版本不支持类型化数组,Opera Mini 也不支持。