我正在尝试迭代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];
}
我可能会考虑使用的另一种方法是将数字乘以(1 + epsilon),但我相信我还需要在比特级解析边缘情况。
答案 0 :(得分:3)
如果您的代码是同步的,则不需要一直致电new
,这意味着您可以保留通过该代码链接的Uint32Array
和Float32Array
所有功能都使用相同的缓冲区,例如
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];
}
};
}());
答案 1 :(得分:1)
这样的东西应该可以工作,并且不需要分配数组:
function testall(f) {
var M = Math.pow(2,-126);
var x;
for (p = -1; p <= 1; p +=2) {
for (s = 0; s < 1<<23; s++) {
// subnormals (including zeros)
x = p*M*(s/(1<<23));
f(x);
}
for (b = M; b <= 2/M; b *= 2) {
for (s = 0; s < 1<<23; s++) {
// normals
x = p*b*(1+s/(1<<23));
f(x);
}
}
}
}
这将迭代所有实值浮点数(次正规值和法线值)。它不会处理Infs(只有两个,所以我留给你)或NaNs(据我所知,没有有效的方法来迭代JavaScript中的所有NaN位模式)。 / p>