JavaScript 中的快速 nextafter 函数

mfd*_*kin 5 javascript floating-point

我正在尝试遍历 JavaScript 中的所有 32 位浮点数,以直观地比较多项式评估的一些方法的准确性。为此,我实现了如下所示的代码。不幸的是,这段代码太慢了。

有什么办法可以提高性能吗?

在 C/C++ 中,等效代码在我的计算机上运行一分钟多一点,而我没有耐心看到这段代码需要多长时间。

function nextFloat(f) {
    // Note that this moves away from 0.0
    // It will fail at +/- infinity and result in an NaN
    var bitRepr = floatToBits(f);
    bitRepr++;
    return bitsToFloat(bitRepr);
}

function prevFloat(f) {
    // Note that this moves towards 0.0
    // This will fail at 0.0 and result in an NaN
    var bitRepr = floatToBits(f);
    bitRepr--;
    return bitsToFloat(bitRepr);
}

function floatToBits(f) {
    var buf = new ArrayBuffer(4);
    (new Float32Array(buf))[0] = f;
    return (new Uint32Array(buf))[0];
}

function bitsToFloat(b) {
    var buf = new ArrayBuffer(4);
    (new Uint32Array(buf))[0] = b;
    return (new Float32Array(buf))[0];
}
Run Code Online (Sandbox Code Playgroud)

我可能会考虑使用的另一种方法是将数字乘以 (1 + epsilon),尽管我相信有一些边缘情况,无论如何我都需要在位级别解决。

Pau*_* S. 4

如果你的代码是同步的,你不需要一直调用new,这意味着你可以保持你的Uint32ArrayFloat32Array是通过所有函数的同一个缓冲区链接的,例如

var obj = (function () {
    var int = new Uint32Array(1),
        float = new Float32Array(int.buffer);
    return {
        i2f: function (i) {
            int[0] = i;
            return float[0];
        },
        f2i: function (f) {
            float[0] = f;
            return int[0];
        },
        next: function () {
            int[0] = int[0] + 1;
            return float[0];
        },
        prev: function () {
            int[0] = int[0] - 1;
            return float[0];
        }
    };
}());
Run Code Online (Sandbox Code Playgroud)

  • 我个人不会选择将您的对象命名为“int”和“float”。对于任何了解使用这些类型的语言的人来说,这段代码似乎相当具有误导性。 (4认同)