这个问题与此有关,但是因为我尝试优化功能以提高速度,所以我将这个问题作为一个新问题提出。
我正在将新的浮动 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
更快吗?