0

这个问题与有关,但是因为我尝试优化功能以提高速度,所以我将这个问题作为一个新问题提出。

我正在将新的浮动 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更快吗?

4

1 回答 1

1

ADataView是一个更适合从缓冲区中读取不同类型的类,而不是在缓冲区上创建不同类型的数组。这是您DoubleToInt64Bits重写以使用DataView.

function DoubleToInt64Bits(A, xInt)
{
    var dataView = new DataView(buf);
    dataView.setFloat64(0, A);
    xInt.lo = dataView.getUint32(4) | 0;
    xInt.hi = dataView.getInt32(0) | 0;
}

这将我的运行时间从 ~1500ms 减少到 ~850ms。

于 2014-01-24T08:10:38.293 回答