在javascript中测试“双重”平等

我已经将Clipper库的实验性C#“float”版本翻译成了 javascript。 在最新的沙盒版本中,有一个函数IsAlmostEqual似乎很难翻译。 由于数值稳定性问题,无法使用==运算符比较双重等式,因此需要此函数来处理这些问题。

-9223372036854775808 - aInt-9223372036854775808 - bInt很容易用BigInteger库计算,但BitConverter.DoubleToInt64Bits更难。

知道如何将IsAlmostEqual函数转换为javascript吗? 或者具体如何实现BitConverter.DoubleToInt64Bits到javascript?

 private static bool IsAlmostEqual(double A, double B) { //http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm Int64 aInt = BitConverter.DoubleToInt64Bits(A); if (aInt < 0) aInt = unchecked(-9223372036854775808 - aInt); Int64 bInt = BitConverter.DoubleToInt64Bits(B); if (bInt < 0) bInt = unchecked(-9223372036854775808 - bInt); return (Math.Abs(aInt - bInt) <= 10000000000); } 

数值稳定性和鲁棒性:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
http://www.mpi-inf.mpg.de/~kettner/pub/nonrobust_cgta_06.pdf
http://cpc.cs.qub.ac.uk/MRSN/higham.pdf
http://www.2ality.com/2012/04/number-encoding.html

我最终使用完全不同的函数来测试双重相等。 原始函数使用双重的有符号int64表示,这在Javascript中是不可能的,不使用慢速和复杂的按位运算或使用某些BigDecimal库。 它使用相对误差和绝对误差的组合。

 var IsAlmostEqual = function(a,b)
 {
   if(a == b)返回true;
   var diff = Math.abs(a  -  b);
   if(diff <4.94065645841247E-320)返回true;
   a = Math.abs(a);
   b = Math.abs(b);
   var smallest =(b 

根据我的测试,它似乎可靠。 请在jsbin中测试。

编辑:我更新了上面的代码。 现在它在所有83个测试用例中使用ULP技术产生相同的结果(使用maxUpls 10,000)。 由于Javascript缺少64位整数,ULP技术比EPSILON技术慢8x-20x。