JavaScript包整数并计算任意精度浮点数:

时间:2011-07-20 06:40:07

标签: javascript binary-data integer arbitrary-precision

我需要在JavaScript中执行以下操作,并且到目前为止无法找到无缝地执行此操作的解决方案:

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

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

  • 我需要将它转换为任意精度,非指数形式,所以:

    0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000108830763893050000000000000000000000000000000000000000000000000000000000000000000000000000

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

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

谢谢!

注意:我确实需要“打包/解包”才能忠实地表示转换为双/ 64位浮点数的两个数字。但我不关心,比如导出到字符串或原始缓冲区。只要我得到双精度的任意精度双重表示就可以了。

2 个答案:

答案 0 :(得分:4)

1:Khronos对于 DataView 接口有specification in progress作为WebGL TypedArray 要求的一部分, Int32Array Float64Array 会让您将两个整数写入缓冲区,然后将它们作为双精度读出来。

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

如果没有上面的 TypedArray 支持,我认为没有办法使用bit-twiddling来实现这一点,因为Javascript的位运算符将数字视为32位无符号值,所以你' d无法访问高阶位。

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

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

NB - double的指数范围是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
  7. 编辑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 代码被修复以解决特殊情况。

答案 1 :(得分:0)

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