この質問はこれに関連していますが、関数を高速化するために最適化しようとしているため、この質問を新しいものとして質問します。
私はAngus JohnsonからJavascriptに新しいフロートClipperライブラリを翻訳しています.UlpテクニックIsAlmostEqual
を使用してdoubleの等価性を比較する関数があります。
元の C# 関数は次のとおりです。
public static bool IsAlmostEqual(double A, double B) { //http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm const int maxUlps = 10000; Int64 aInt = BitConverter.DoubleToInt64Bits(A); if (aInt < 0) aInt = Int64.MinValue - aInt; Int64 bInt = BitConverter.DoubleToInt64Bits(B); if (bInt < 0) bInt = Int64.MinValue - bInt; Int64 sub = unchecked(aInt - bInt); if (sub > aInt != bInt < 0) は false を返します。 return (サブ <= 0 && サブ > -maxUlps) || (サブ > 0 && サブ < maxUlps); }
そしてそれの私の翻訳(JSBINで):
var IsAlmostEqual_Ulps = 関数 (A, B) { DoubleToInt64Bits(A, aInt); if(aInt.hi < 0) aInt = 減算 (Int64_MinValue, aInt); DoubleToInt64Bits(B, bInt); if(bInt.hi < 0) bInt = 減算(Int64_MinValue, bInt); var サブ = 減算 (aInt、bInt); if (sub.hi < 0) sub = negate(sub); if (lessthan(sub, maxUlps)) は true を返します。 false を返します。 }
私の Javascript バージョンは 83 のサンプル値によると問題なく動作するようですが、問題は主にDoubleToInt64Bits
関数に起因する遅さです。コードがスタンドアロンの html (JSBIN の外部) として実行される場合、合計実行時間は約 2267 ミリ秒で、そのうちDoubleToInt64Bits
983 ミリ秒かかります。
問題のある (=遅い)DoubleToInt64Bits
は次のとおりです。
関数 DoubleToInt64Bits(A, xInt) { (新しい Float64Array(buf))[0] = A; xInt.lo = (新しい Uint32Array(buf))[0] | 0; xInt.hi = (新しい Int32Array(buf))[1] | 0; }
DoubleToInt64Bits
速くする方法はありますか?