2

我需要在 JavaScript 中执行以下操作,但迄今为止无法找到无缝执行此操作的解决方案:

  • 以特定顺序获取两个整数并像 Python 的 struct 模块一样打包它们。
  • 这个打包的值,(支持与主机不同的字节顺序的奖励)将转换为 64 位浮点数(双精度)。它们必须是任意的,因此我可能会得到整数的指数表示(例如,它们可能是 0xdeadbeef 和 500):

    exp 形式:1.0883076389305e-311 1.0883076389305000 * 10 ^ - 311

  • 我需要将其转换为任意精度、非指数形式,因此:

    0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000108830763893050000000000000000000000000000000000000000000000000000000000000000000000000000

  • 该数字转换为字符串:)

我还没有找到一种在 Javascript 中执行此操作的方法,我必须输出一些必须支持任意精度的数字,或者至少支持双精度的 1024 指数(或者说 400)。

谢谢!!

注意:我确实需要“打包/解包”来忠实地表示这两个数字转换为双精度/64 位浮点数。但我不关心,比如说,导出到字符串或原始缓冲区。只要我为 double 获得任意精度的 double 表示,一切都很好。

4

2 回答 2

4

1:作为 WebGL要求的一部分, Khronos正在制定一个接口规范,该规范与并允许您将两个 int 写入缓冲区,并将它们作为 double 读回。DataViewTypedArrayInt32ArrayFloat64Array

不幸的是,浏览器对此的支持还不常见 - 要测试您的浏览器,请访问http://html5test.com/并查看标题为“本机二进制数据”的部分。

如果没有TypedArray上面的支持,我认为没有任何方法可以使用位旋转来做到这一点,因为 Javascript 的位运算符将数字视为 32 位无符号值,因此您无法访问高阶位。

2:double变量没有任何特定的形式,IEE754只是一个内部表示。

3:这是您可以尝试显示实际精度的点。不幸的是,内置方法,例如Number.toFixed(),不支持显示超过 20 位小数。您将需要解析指数形式并手动构造一个具有适当数量的前导零的字符串。

注意 - 双精度的指数范围是 2^1024,而不是 10^1024,因此实际限制实际上是 ~1.0E±308 - 您的示例数字小于该范围。

编辑实际上,可能有一种方法,但我不能保证这个的精度:

  1. 取你的两个整数,称它们为hilo
  2. 提取指数 -exp = (hi >> 20) & 0x7ff
  3. 提取符号 -sign = (hi >> 31)
  4. 提取尾数 -((hi & 0xfffff) * Math.pow(2, 32) + lo) / Math.pow(2, 52)
  5. result = (1 + m) * (Math.pow(2.0, exp - 1023))
  6. if (sign) result *= -1

编辑 2 - 它有效!见http://jsfiddle.net/alnitak/assXS/

var hex2double = function(input) {

    var hi = parseInt(input.substring(0, 8), 16);
    var lo = parseInt(input.substring(8   ), 16);

    var p32 = 0x100000000;
    var p52 = 0x10000000000000;

    var exp = (hi >> 20) & 0x7ff;
    var sign = (hi >> 31);
    var m = 1 + ((hi & 0xfffff) * p32 + lo) / p52;
    m = exp ? (m + 1) : (m * 2.0);

    return (sign ? -1 : 1) * m * Math.pow(2, exp - 1023);
};

在http://babbage.cs.qc.edu/IEEE-754/Decimal.html输入一个浮点数,从输出的底行获取生成的十六进制字符串,并将其传递给上面的函数。您应该会看到一个包含原始值的警报。

编辑 3代码修复了指数位全为零时的特殊情况。

于 2011-07-20T06:53:28.123 回答
0

我认为您需要一个用于 JavaScript 的大数字库,例如http://jsfromhell.com/classes/bignumber

于 2011-07-20T07:25:07.623 回答