这个问题与此有关,但是因为我尝试优化功能以提高速度,所以我将这个问题作为一个新问题提出。
我正在将新的浮动 Clipper 库从 Angus Johnson 转换为 Javascript,并且有一个函数,它使用Ulps技术IsAlmostEqual比较双打的相等性。
原始的 C# 函数在这里:
公共静态布尔IsAlmostEqual(双A,双B)
{
//http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
常量 int maxUlps = 10000;
Int64 aInt = BitConverter.DoubleToInt64Bits(A);
if (aInt < 0) aInt = Int64.MinValue - aInt;
Int64 bInt = BitConverter.DoubleToInt64Bits(B);
如果 (bInt < 0) bInt = Int64.MinValue - bInt;
Int64 sub = unchecked(aInt - bInt);
if (sub > aInt != bInt < 0) 返回假;
返回 (sub <= 0 && sub > -maxUlps) || (sub > 0 && sub < maxUlps);
}
我对它的翻译(在JSBIN中):
var IsAlmostEqual_Ulps = 函数(A,B)
{
DoubleToInt64Bits(A, aInt);
如果(aInt.hi < 0)aInt = 减法(Int64_MinValue,aInt);
DoubleToInt64Bits(B, bInt);
如果(bInt.hi < 0)bInt = 减法(Int64_MinValue,bInt);
var sub = 减法(aInt,bInt);
if (sub.hi < 0) sub = negate(sub);
如果(小于(sub,maxUlps))返回true;
返回假;
}
根据 83 个样本值,我的 Javascript 版本似乎可以正常工作,但问题是速度慢,主要来自DoubleToInt64Bits功能。当代码作为独立的 html(JSBIN 之外)执行时,总运行时间约为 2267 毫秒,其中DoubleToInt64Bits需要 983 毫秒。
有问题的(=慢)DoubleToInt64Bits在这里:
函数 DoubleToInt64Bits(A, xInt)
{
(新的 Float64Array(buf))[0] = A;
xInt.lo = (new Uint32Array(buf))[0] | 0;
xInt.hi = (new Int32Array(buf))[1] | 0;
}
有什么方法可以DoubleToInt64Bits更快吗?