JavaScript中的Fast nextafter函数
我试图在JavaScript中遍历所有32位浮点数,以直观地比较多项式求值方法的准确性。为此,我实现了如下所示的代码。不幸的是,这段代码太慢了 有没有办法提高绩效 在C/C++中,等价的代码在我的计算机上运行一分钟多一点,而我却没有耐心去看这个代码需要多长时间JavaScript中的Fast nextafter函数,javascript,floating-point,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
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 +ε),虽然我相信有边缘情况,我将需要解决的位级无论如何。< /P> < P>如果你的代码是同步的,你不需要一直调用<代码>新< /代码>,这意味着您可以保留
uint32数组
和float32数组
,它们通过相同的缓冲区链接到所有函数,例如
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];
}
};
}());
这样的方法应该可以工作,并且不需要分配阵列:
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);
}
}
}
}
功能测试(f){
var M=数学功率(2,-126);
var x;
对于(p=-1;p)我个人不会选择将对象命名为int
和float
。对于任何了解使用这些类型的语言的人来说,这段代码似乎都有误导性。这段代码显著提高了性能(在V8的堆管理中有点让我失望…),但它仍然需要相当长的时间才能运行。在一个测试中,运行所有正浮点数大约需要6分钟。还有其他地方我可以节省一些钱吗?由于函数本身的迭代次数可能相当慢,看看是否有改进,将代码直接放入循环中这不是我的答案我希望,因为我不希望大多数程序员知道浮点数作为整数递增是什么。不过,它确实让我达到了(未优化的)C速度的两倍。不幸的是,我猜不会有更多的收益,但这已经足够了。